Browse Source

tools: use tal instead of talloc.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Rusty Russell 13 years ago
parent
commit
dc8042b425
55 changed files with 614 additions and 685 deletions
  1. 5 2
      tools/Makefile
  2. 2 5
      tools/ccan_depends.c
  3. 4 6
      tools/ccan_dir.c
  4. 5 3
      tools/ccanlint/Makefile
  5. 11 14
      tools/ccanlint/async.c
  6. 31 51
      tools/ccanlint/ccanlint.c
  7. 3 2
      tools/ccanlint/ccanlint.h
  8. 31 31
      tools/ccanlint/file_analysis.c
  9. 6 5
      tools/ccanlint/licenses.c
  10. 3 3
      tools/ccanlint/test/run-file_analysis.c
  11. 2 3
      tools/ccanlint/tests/avoids_cpp_reserved.c
  12. 10 12
      tools/ccanlint/tests/depends_accurate.c
  13. 11 13
      tools/ccanlint/tests/depends_build.c
  14. 6 9
      tools/ccanlint/tests/depends_build_without_features.c
  15. 3 6
      tools/ccanlint/tests/depends_exist.c
  16. 80 76
      tools/ccanlint/tests/examples_compile.c
  17. 10 12
      tools/ccanlint/tests/examples_exist.c
  18. 0 1
      tools/ccanlint/tests/examples_relevant.c
  19. 4 5
      tools/ccanlint/tests/examples_run.c
  20. 0 2
      tools/ccanlint/tests/hash_if.c
  21. 4 5
      tools/ccanlint/tests/headers_idempotent.c
  22. 3 4
      tools/ccanlint/tests/info_documentation_exists.c
  23. 4 3
      tools/ccanlint/tests/info_exists.c
  24. 0 1
      tools/ccanlint/tests/info_summary_single_line.c
  25. 0 2
      tools/ccanlint/tests/license_comment.c
  26. 0 3
      tools/ccanlint/tests/license_depends_compat.c
  27. 26 23
      tools/ccanlint/tests/license_exists.c
  28. 0 2
      tools/ccanlint/tests/license_file_compat.c
  29. 3 4
      tools/ccanlint/tests/main_header_compiles.c
  30. 3 2
      tools/ccanlint/tests/main_header_exists.c
  31. 6 6
      tools/ccanlint/tests/module_builds.c
  32. 16 16
      tools/ccanlint/tests/module_links.c
  33. 6 6
      tools/ccanlint/tests/no_trailing_whitespace.c
  34. 2 3
      tools/ccanlint/tests/objects_build.c
  35. 4 6
      tools/ccanlint/tests/objects_build_with_stringchecks.c
  36. 3 3
      tools/ccanlint/tests/objects_build_without_features.c
  37. 7 9
      tools/ccanlint/tests/reduce_features.c
  38. 17 22
      tools/ccanlint/tests/tests_compile.c
  39. 4 5
      tools/ccanlint/tests/tests_compile_coverage.c
  40. 11 15
      tools/ccanlint/tests/tests_coverage.c
  41. 7 8
      tools/ccanlint/tests/tests_exist.c
  42. 1 3
      tools/ccanlint/tests/tests_helpers_compile.c
  43. 7 7
      tools/ccanlint/tests/tests_pass.c
  44. 33 33
      tools/ccanlint/tests/tests_pass_valgrind.c
  45. 2 4
      tools/ccanlint/tests/tests_pass_without_features.c
  46. 1 2
      tools/compile.c
  47. 39 41
      tools/depends.c
  48. 22 23
      tools/doc_extract-core.c
  49. 4 6
      tools/doc_extract.c
  50. 29 34
      tools/manifest.c
  51. 1 1
      tools/manifest.h
  52. 36 44
      tools/namespacize.c
  53. 6 8
      tools/read_config_header.c
  54. 68 61
      tools/tools.c
  55. 12 9
      tools/tools.h

+ 5 - 2
tools/Makefile

@@ -2,13 +2,16 @@ ALL_TOOLS = tools/configurator/configurator tools/ccan_depends tools/doc_extract
 LDLIBS = -lrt
 DEP_OBJS = ccan/err/err.o \
 	ccan/foreach/foreach.o \
+	ccan/list/list.o \
 	ccan/noerr/noerr.o \
 	ccan/rbuf/rbuf.o \
 	ccan/read_write_all/read_write_all.o \
 	ccan/str/debug.o \
 	ccan/str/str.o \
-	ccan/str_talloc/str_talloc.o \
-	ccan/talloc/talloc.o \
+	ccan/take/take.o \
+	ccan/tal/tal.o \
+	ccan/tal/link/link.o \
+	ccan/tal/str/str.o \
 	ccan/time/time.o \
 	tools/read_config_header.o \
 	tools/ccan_dir.o \

+ 2 - 5
tools/ccan_depends.c

@@ -3,7 +3,6 @@
 #include <stdio.h>
 #include <ccan/err/err.h>
 #include <ccan/str/str.h>
-#include <ccan/talloc/talloc.h>
 
 int main(int argc, char *argv[])
 {
@@ -43,11 +42,9 @@ int main(int argc, char *argv[])
 		errx(1, "--non-ccan needs --compile");
 
 	if (compile)
-		deps = get_deps(talloc_autofree_context(), argv[1],
-				style, recurse, compile_info);
+		deps = get_deps(NULL, argv[1], style, recurse, compile_info);
 	else
-		deps = get_safe_ccan_deps(talloc_autofree_context(),
-					  argv[1], style, recurse);
+		deps = get_safe_ccan_deps(NULL, argv[1], style, recurse);
 
 	for (i = 0; deps[i]; i++)
 		if (strstarts(deps[i], "ccan/") == ccan)

+ 4 - 6
tools/ccan_dir.c

@@ -1,4 +1,3 @@
-#include <ccan/talloc/talloc.h>
 #include <ccan/err/err.h>
 #include "tools.h"
 #include <assert.h>
@@ -27,14 +26,13 @@ const char *find_ccan_dir(const char *base)
 
 	if (!ccan_dir) {
 		if (base[0] != '/') {
-			const char *tmpctx = talloc_getcwd(NULL);
-			find_ccan_dir(talloc_asprintf(tmpctx, "%s/%s",
-						      tmpctx, base));
-			talloc_free(tmpctx);
+			const char *tmpctx = tal_getcwd(NULL);
+			find_ccan_dir(tal_fmt(tmpctx, "%s/%s", tmpctx, base));
+			tal_free(tmpctx);
 		} else {
 			unsigned int prefix = ccan_dir_prefix(base);
 			if (prefix)
-				ccan_dir = talloc_strndup(NULL, base, prefix);
+				ccan_dir = tal_strndup(NULL, base, prefix);
 		}
 	}
 	return ccan_dir;

+ 5 - 3
tools/ccanlint/Makefile

@@ -10,6 +10,7 @@ CORE_OBJS := \
 	ccan/htable/htable.o \
 	ccan/ilog/ilog.o \
 	ccan/lbalance/lbalance.o \
+	ccan/list/list.o \
 	ccan/noerr/noerr.o \
 	ccan/opt/helpers.o \
 	ccan/opt/opt.o \
@@ -19,10 +20,11 @@ CORE_OBJS := \
 	ccan/rbuf/rbuf.o \
 	ccan/read_write_all/read_write_all.o \
 	ccan/str/str.o ccan/str/debug.o \
-	ccan/str_talloc/str_talloc.o \
 	ccan/strmap/strmap.o \
-	ccan/talloc/talloc.o \
-	ccan/talloc_link/talloc_link.o \
+	ccan/take/take.o \
+	ccan/tal/tal.o \
+	ccan/tal/link/link.o \
+	ccan/tal/str/str.o \
 	ccan/time/time.o \
 	tools/ccanlint/async.o \
 	tools/ccanlint/ccanlint.o \

+ 11 - 14
tools/ccanlint/async.c

@@ -13,7 +13,6 @@
 #include <ccan/lbalance/lbalance.h>
 #include <ccan/tlist/tlist.h>
 #include <ccan/time/time.h>
-#include <ccan/talloc/talloc.h>
 
 static struct lbalance *lb;
 TLIST_TYPE(command, struct command);
@@ -91,7 +90,7 @@ static void run_more(void)
 	}
 }
 
-static int destroy_command(struct command *command)
+static void destroy_command(struct command *command)
 {
 	if (!command->done && command->pid) {
 		kill(-command->pid, SIGKILL);
@@ -100,7 +99,6 @@ static int destroy_command(struct command *command)
 	}
 
 	tlist_del(command, list);
-	return 0;
 }
 
 void run_command_async(const void *ctx, unsigned int time_ms,
@@ -114,17 +112,18 @@ void run_command_async(const void *ctx, unsigned int time_ms,
 	if (!lb)
 		lb = lbalance_new();
 
-	command = talloc(ctx, struct command);
+	command = tal(ctx, struct command);
 	command->ctx = ctx;
 	command->time_ms = time_ms;
 	command->pid = 0;
-	command->output = talloc_strdup(command, "");
+	/* We want to track length, so don't use tal_strdup */
+	command->output = tal_arrz(command, char, 1);
 	va_start(ap, fmt);
-	command->command = talloc_vasprintf(command, fmt, ap);
+	command->command = tal_vfmt(command, fmt, ap);
 	va_end(ap);
 	tlist_add_tail(&pending, command, list);
 	command->done = false;
-	talloc_set_destructor(command, destroy_command);
+	tal_add_destructor(command, destroy_command);
 
 	run_more();
 }
@@ -150,14 +149,12 @@ static void reap_output(void)
 		if (FD_ISSET(c->output_fd, &in)) {
 			int old_len, len;
 			/* This length includes nul terminator! */
-			old_len = talloc_array_length(c->output);
-			c->output = talloc_realloc(c, c->output, char,
-						   old_len + 1024);
+			old_len = tal_count(c->output);
+			tal_resize(&c->output, old_len + 1024);
 			len = read(c->output_fd, c->output + old_len - 1, 1024);
 			if (len < 0)
 				err(1, "Reading from async command");
-			c->output = talloc_realloc(c, c->output, char,
-						   old_len + len);
+			tal_resize(&c->output, old_len + len);
 			c->output[old_len + len - 1] = '\0';
 			if (len == 0) {
 				struct rusage ru;
@@ -197,8 +194,8 @@ void *collect_command(bool *ok, char **output)
 
 	*ok = (WIFEXITED(c->status) && WEXITSTATUS(c->status) == 0);
 	ctx = c->ctx;
-	*output = talloc_steal(ctx, c->output);
-	talloc_free(c);
+	*output = tal_steal(ctx, c->output);
+	tal_free(c);
 	return (void *)ctx;
 }
 

+ 31 - 51
tools/ccanlint/ccanlint.c

@@ -27,8 +27,7 @@
 #include <err.h>
 #include <ctype.h>
 #include <ccan/str/str.h>
-#include <ccan/str_talloc/str_talloc.h>
-#include <ccan/talloc/talloc.h>
+#include <ccan/take/take.h>
 #include <ccan/opt/opt.h>
 #include <ccan/foreach/foreach.h>
 #include <ccan/cast/cast.h>
@@ -117,7 +116,7 @@ static bool run_test(struct dgraph_node *n, struct run_info *run)
 	if (i->done)
 		return true;
 
-	score = talloc(run->m, struct score);
+	score = tal(run->m, struct score);
 	list_head_init(&score->per_file_errors);
 	score->error = NULL;
 	score->pass = false;
@@ -213,7 +212,7 @@ static void register_test(struct ccanlint *test)
 {
 	if (!strmap_add(&tests, test->key, test))
 		err(1, "Adding test %s", test->key);
-	test->options = talloc_array(NULL, char *, 1);
+	test->options = tal_arr(NULL, char *, 1);
 	test->options[0] = NULL;
 	dgraph_init_node(&test->node);
 }
@@ -257,7 +256,7 @@ bool is_excluded(const char *name)
 
 static bool init_deps(const char *member, struct ccanlint *c, void *unused)
 {
-	char **deps = strsplit(NULL, c->needs, " ");
+	char **deps = tal_strsplit(NULL, c->needs, " ", STR_EMPTY_OK);
 	unsigned int i;
 
 	for (i = 0; deps[i]; i++) {
@@ -269,7 +268,7 @@ static bool init_deps(const char *member, struct ccanlint *c, void *unused)
 			     deps[i], c->key);
 		dgraph_add_edge(&dep->node, &c->node);
 	}
-	talloc_free(deps);
+	tal_free(deps);
 	return true;
 }
 
@@ -339,10 +338,9 @@ static void print_test_depends(void)
 }
 
 
-static int show_tmpdir(const char *dir)
+static void show_tmpdir(const char *dir)
 {
 	printf("You can find ccanlint working files in '%s'\n", dir);
-	return 0;
 }
 
 static char *keep_tests(void *unused)
@@ -350,7 +348,8 @@ static char *keep_tests(void *unused)
 	keep_results = true;
 
 	/* Don't automatically destroy temporary dir. */
-	talloc_set_destructor(temp_dir(NULL), show_tmpdir);
+	keep_temp_dir();
+	tal_add_destructor(temp_dir(), show_tmpdir);
 	return NULL;
 }
 
@@ -366,8 +365,7 @@ static char *exclude_test(const char *testname, void *unused)
 {
 	struct ccanlint *i = find_test(testname);
 	if (!i)
-		return talloc_asprintf(NULL, "No test %s to --exclude",
-				       testname);
+		return tal_fmt(NULL, "No test %s to --exclude", testname);
 
 	/* Remove this, and everything which depends on it. */
 	dgraph_traverse_from(&i->node, remove_test, "excluded on command line");
@@ -441,21 +439,6 @@ static char *test_dependency_graph(void *arg)
 	exit(0);
 }
 
-/* Remove empty lines. */
-static char **collapse(char **lines, unsigned int *nump)
-{
-	unsigned int i, j;
-	for (i = j = 0; lines[i]; i++) {
-		if (lines[i][0])
-			lines[j++] = lines[i];
-	}
-	lines[j] = NULL;
-	if (nump)
-		*nump = j;
-	return lines;
-}
-
-
 static void add_options(struct ccanlint *test, char **options,
 			unsigned int num_options)
 {
@@ -465,11 +448,9 @@ static void add_options(struct ccanlint *test, char **options,
 		num = 0;
 	else
 		/* -1, because last one is NULL. */
-		num = talloc_array_length(test->options) - 1;
+		num = tal_count(test->options) - 1;
 
-	test->options = talloc_realloc(NULL, test->options,
-				       char *,
-				       num + num_options + 1);
+	tal_resize(&test->options, num + num_options + 1);
 	memcpy(&test->options[num], options, (num_options + 1)*sizeof(char *));
 }
 
@@ -484,10 +465,9 @@ void add_info_options(struct ccan_file *info)
 			continue;
 
 		for (i = 0; i < d->num_lines; i++) {
-			unsigned int num_words;
-			char **words = collapse(strsplit(d, d->lines[i], " \t"),
-						&num_words);
-			if (num_words == 0)
+			char **words = tal_strsplit(d, d->lines[i], " \t",
+						    STR_NO_EMPTY);
+			if (!words[0])
 				continue;
 
 			if (strncmp(words[0], "//", 2) == 0)
@@ -516,7 +496,7 @@ void add_info_options(struct ccan_file *info)
 				if (!test->takes_options)
 					warnx("%s: %s doesn't take options",
 					      info->fullname, words[0]);
-				add_options(test, words+1, num_words-1);
+				add_options(test, words+1, tal_count(words)-1);
 			}
 		}
 	}
@@ -532,7 +512,7 @@ char **per_file_options(const struct ccanlint *test, struct ccan_file *f)
 	if (!test->options[0])
 		return test->options;
 
-	ret = talloc_array(f, char *, talloc_array_length(test->options));
+	ret = tal_arr(f, char *, tal_count(test->options));
 	for (i = 0; test->options[i]; i++) {
 		char *optname;
 
@@ -546,7 +526,7 @@ char **per_file_options(const struct ccanlint *test, struct ccan_file *f)
 
 		/* FAIL overrides anything else. */
 		if (streq(optname, "FAIL")) {
-			ret = talloc_array(f, char *, 2);
+			ret = tal_arr(f, char *, 2);
 			ret[0] = (char *)"FAIL";
 			ret[1] = NULL;
 			return ret;
@@ -555,8 +535,9 @@ char **per_file_options(const struct ccanlint *test, struct ccan_file *f)
 	}
 	ret[j] = NULL;
 
-	/* Shrink it to size so talloc_array_length() works as expected. */
-	return talloc_realloc(NULL, ret, char *, j + 1);
+	/* Shrink it to size so tal_array_length() works as expected. */
+	tal_resize(&ret, j + 1);
+	return ret;
 }
 
 static char *opt_set_const_charp(const char *arg, const char **p)
@@ -568,7 +549,7 @@ static char *opt_set_target(const char *arg, struct dgraph_node *all)
 {
 	struct ccanlint *t = find_test(arg);
 	if (!t)
-		return talloc_asprintf(NULL, "unknown --target %s", arg);
+		return tal_fmt(NULL, "unknown --target %s", arg);
 
 	targeting = true;
 	dgraph_add_edge(&t->node, all);
@@ -609,7 +590,7 @@ int main(int argc, char *argv[])
 	unsigned int i;
 	struct manifest *m;
 	const char *prefix = "";
-	char *dir = talloc_getcwd(NULL), *base_dir = dir, *testlink;
+	char *dir = tal_getcwd(NULL), *base_dir = dir, *testlink;
 	struct dgraph_node all;
 	
 	/* Empty graph node to which we attach everything else. */
@@ -647,8 +628,8 @@ int main(int argc, char *argv[])
 	opt_early_parse(argc, argv, opt_log_stderr_exit);
 
 	/* We move into temporary directory, so gcov dumps its files there. */
-	if (chdir(temp_dir(talloc_autofree_context())) != 0)
-		err(1, "Error changing to %s temporary dir", temp_dir(NULL));
+	if (chdir(temp_dir()) != 0)
+		err(1, "Error changing to %s temporary dir", temp_dir());
 
 	init_tests();
 
@@ -665,7 +646,7 @@ int main(int argc, char *argv[])
 		strmap_iterate(&tests, add_to_all, &all);
 
 	/* This links back to the module's test dir. */
-	testlink = talloc_asprintf(NULL, "%s/test", temp_dir(NULL));
+	testlink = tal_fmt(NULL, "%s/test", temp_dir());
 
 	/* Defaults to pwd. */
 	if (argc == 1) {
@@ -677,8 +658,7 @@ int main(int argc, char *argv[])
 		dir = argv[i];
 
 		if (dir[0] != '/')
-			dir = talloc_asprintf_append(NULL, "%s/%s",
-						     base_dir, dir);
+			dir = tal_fmt(NULL, "%s/%s", base_dir, dir);
 		while (strends(dir, "/"))
 			dir[strlen(dir)-1] = '\0';
 
@@ -695,16 +675,16 @@ int main(int argc, char *argv[])
 		}
 
 		if (dir != base_dir)
-			prefix = talloc_append_string(talloc_basename(NULL,dir),
-						      ": ");
+			prefix = tal_strcat(NULL, take(tal_basename(NULL,dir)),
+					    ": ");
 
-		m = get_manifest(talloc_autofree_context(), dir);
+		m = get_manifest(autofree(), dir);
 
 		/* Create a symlink from temp dir back to src dir's
 		 * test directory. */
 		unlink(testlink);
-		if (symlink(talloc_asprintf(m, "%s/test", dir), testlink) != 0)
-			err(1, "Creating test symlink in %s", temp_dir(NULL));
+		if (symlink(tal_fmt(m, "%s/test", dir), testlink) != 0)
+			err(1, "Creating test symlink in %s", temp_dir());
 
 		if (!run_tests(&all, summary, m, prefix))
 			pass = false;

+ 3 - 2
tools/ccanlint/ccanlint.h

@@ -2,6 +2,7 @@
 #define CCAN_LINT_H
 #include "config.h"
 #include <ccan/list/list.h>
+#include <ccan/tal/tal.h>
 #include <ccan/dgraph/dgraph.h>
 #include <ccan/autodata/autodata.h>
 #include <stdbool.h>
@@ -55,7 +56,7 @@ struct ccanlint {
 	bool compulsory;
 
 	/* If timeleft is set to 0, means it timed out.
-	 * score is the result, and a talloc context freed after all our
+	 * score is the result, and a tal context freed after all our
 	 * depends are done. */
 	void (*check)(struct manifest *m,
 		      unsigned int *timeleft, struct score *score);
@@ -137,7 +138,7 @@ enum line_compiled get_ccan_line_pp(struct pp_conditions *cond,
 
 /* Get token if it's equal to token. */
 bool get_token(const char **line, const char *token);
-/* Talloc copy of symbol token, or NULL.  Increment line. */
+/* Tal copy of symbol token, or NULL.  Increment line. */
 char *get_symbol_token(void *ctx, const char **line);
 
 /* Similarly for ->doc_sections */

+ 31 - 31
tools/ccanlint/file_analysis.c

@@ -1,9 +1,7 @@
 #include "config.h"
 #include "ccanlint.h"
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
-#include <ccan/str_talloc/str_talloc.h>
-#include <ccan/talloc_link/talloc_link.h>
+#include <ccan/take/take.h>
 #include <ccan/hash/hash.h>
 #include <ccan/htable/htable_type.h>
 #include <ccan/noerr/noerr.h>
@@ -38,10 +36,11 @@ struct list_head *get_ccan_file_docs(struct ccan_file *f)
  * @in_comment: are we already within a comment (from prev line).
  * @unterminated: are we still in a comment for next line.
  */
-static char *remove_comments(const char *line, bool in_comment,
+static char *remove_comments(const tal_t *ctx,
+			     const char *line, bool in_comment,
 			     bool *unterminated)
 {
-	char *p, *ret = talloc_array(line, char, strlen(line) + 1);
+	char *p, *ret = tal_arr(ctx, char, strlen(line) + 1);
 
 	p = ret;
 	for (;;) {
@@ -121,7 +120,7 @@ static bool parse_hash_if(struct pp_conditions *cond, const char **line)
 
 	/* FIXME: We just chain them, ignoring operators. */
 	if (get_token(line, "||") || get_token(line, "&&")) {
-		struct pp_conditions *sub = talloc(cond, struct pp_conditions);
+		struct pp_conditions *sub = tal(cond, struct pp_conditions);
 
 		sub->parent = cond->parent;
 		sub->type = PP_COND_IFDEF;
@@ -137,10 +136,10 @@ static struct pp_conditions *analyze_directive(struct ccan_file *f,
 					       const char *line,
 					       struct pp_conditions *parent)
 {
-	struct pp_conditions *cond = talloc(f, struct pp_conditions);
+	struct pp_conditions *cond = tal(f, struct pp_conditions);
 	bool unused;
 
-	line = remove_comments(line, false, &unused);
+	line = remove_comments(f, line, false, &unused);
 
 	cond->parent = parent;
 	cond->type = PP_COND_IFDEF;
@@ -187,7 +186,7 @@ static struct pp_conditions *analyze_directive(struct ccan_file *f,
 		cond->inverse = !cond->inverse;
 		return cond;
 	} else if (get_token(&line, "endif")) {
-		talloc_free(cond);
+		tal_free(cond);
 		/* Malformed? */
 		if (!parent)
 			return NULL;
@@ -195,7 +194,7 @@ static struct pp_conditions *analyze_directive(struct ccan_file *f,
 		return parent->parent;
 	} else {
 		/* Not a conditional. */
-		talloc_free(cond);
+		tal_free(cond);
 		return parent;
 	}
 
@@ -219,7 +218,7 @@ struct line_info *get_ccan_line_info(struct ccan_file *f)
 		return f->line_info;
 
 	get_ccan_file_lines(f);
-	f->line_info = talloc_array(f->lines, struct line_info, f->num_lines);
+	f->line_info = tal_arr(f->lines, struct line_info, f->num_lines);
 
 	for (i = 0; i < f->num_lines; continued = continues(f->lines[i++])) {
 		char *p;
@@ -233,7 +232,7 @@ struct line_info *get_ccan_line_info(struct ccan_file *f)
 			/* Same as last line. */
 			f->line_info[i].type = f->line_info[i-1].type;
 			/* Update in_comment. */
-			remove_comments(f->lines[i], in_comment, &in_comment);
+			remove_comments(f, f->lines[i], in_comment, &in_comment);
 			continue;
 		}
 
@@ -248,7 +247,7 @@ struct line_info *get_ccan_line_info(struct ccan_file *f)
 		still_doc_line = (in_comment
 				  && f->line_info[i-1].type == DOC_LINE);
 
-		p = remove_comments(f->lines[i], in_comment, &in_comment);
+		p = remove_comments(f, f->lines[i], in_comment, &in_comment);
 		if (is_empty(p)) {
 			if (strstarts(f->lines[i], "/**") || still_doc_line)
 				f->line_info[i].type = DOC_LINE;
@@ -256,7 +255,7 @@ struct line_info *get_ccan_line_info(struct ccan_file *f)
 				f->line_info[i].type = COMMENT_LINE;
 		} else
 			f->line_info[i].type = CODE_LINE;
-		talloc_free(p);
+		tal_free(p);
 	}
 	return f->line_info;
 }
@@ -330,7 +329,7 @@ static enum line_compiled get_pp(struct pp_conditions *cond,
 static void add_symbol(struct list_head *head,
 		       const char *symbol, const unsigned int *value)
 {
-	struct symbol *sym = talloc(head, struct symbol);
+	struct symbol *sym = tal(head, struct symbol);
 	sym->name = symbol;
 	sym->value = value;
 	list_add(head, &sym->list);
@@ -345,7 +344,7 @@ enum line_compiled get_ccan_line_pp(struct pp_conditions *cond,
 	struct list_head *head;
 	va_list ap;
 
-	head = talloc(NULL, struct list_head);
+	head = tal(NULL, struct list_head);
 	list_head_init(head);
 
 	va_start(ap, value);
@@ -356,7 +355,7 @@ enum line_compiled get_ccan_line_pp(struct pp_conditions *cond,
 		add_symbol(head, symbol, value);
 	}
 	ret = get_pp(cond, head);
-	talloc_free(head);
+	tal_free(head);
 	return ret;
 }
 
@@ -365,33 +364,34 @@ void score_file_error(struct score *score, struct ccan_file *f, unsigned line,
 {
 	va_list ap;
 
-	struct file_error *fe = talloc(score, struct file_error);
+	struct file_error *fe = tal(score, struct file_error);
 	fe->file = f;
 	fe->line = line;
 	list_add_tail(&score->per_file_errors, &fe->list);
 
 	if (!score->error)
-		score->error = talloc_strdup(score, "");
+		score->error = tal_strdup(score, "");
 	
-	if (verbose < 2 && strcount(score->error, "\n") > 5)
+	if (verbose < 2 && strcount(score->error, "\n") > 5) {
+		if (!strends(score->error,
+			     "... more (use -vv to see them all)\n")) {
+			score->error = tal_strcat(score,
+						  take(score->error),
+						  "... more (use -vv to see"
+						  " them all)\n");
+		}
 		return;
+	}
 
 	if (line)
-		score->error = talloc_asprintf_append(score->error,
-						      "%s:%u:",
-						      f->fullname, line);
+		tal_append_fmt(&score->error, "%s:%u:", f->fullname, line);
 	else
-		score->error = talloc_asprintf_append(score->error,
-						      "%s:", f->fullname);
+		tal_append_fmt(&score->error, "%s:", f->fullname);
 
 	va_start(ap, errorfmt);
-	score->error = talloc_vasprintf_append(score->error, errorfmt, ap);
+	tal_append_vfmt(&score->error, errorfmt, ap);
 	va_end(ap);
-	score->error = talloc_append_string(score->error, "\n");
-
-	if (verbose < 2 && strcount(score->error, "\n") > 5)
-		score->error = talloc_append_string(score->error,
-				    "... more (use -vv to see them all)\n");
+	score->error = tal_strcat(score, take(score->error),"\n");
 }
 
 char *get_or_compile_info(const void *ctx, const char *dir)

+ 6 - 5
tools/ccanlint/licenses.c

@@ -1,8 +1,8 @@
 #include "licenses.h"
 #include "ccanlint.h"
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
-#include <ccan/str_talloc/str_talloc.h>
+#include <ccan/tal/tal.h>
+#include <ccan/tal/str/str.h>
 
 const struct license_info licenses[] = {
 	{ "LGPLv2+", "LGPL",
@@ -155,9 +155,10 @@ enum license which_license(struct doc_section *d)
 		return LICENSE_BSD;
 	if (streq(d->lines[0], "CC0"))
 		return LICENSE_CC0;
-	if (strreg(NULL, d->lines[0], "CC0 \\([Pp]ublic [Dd]omain\\)", NULL))
+	if (tal_strreg(NULL, d->lines[0], "CC0 \\([Pp]ublic [Dd]omain\\)",
+		       NULL))
 		return LICENSE_CC0;
-	if (strreg(NULL, d->lines[0], "[Pp]ublic [Dd]omain"))
+	if (tal_strreg(NULL, d->lines[0], "[Pp]ublic [Dd]omain"))
 		return LICENSE_PUBLIC_DOMAIN;
 
 	return LICENSE_UNKNOWN;
@@ -169,7 +170,7 @@ const char *get_ccan_simplified(struct ccan_file *f)
 		unsigned int i, j;
 
 		/* Simplify for easy matching: only alnum and single spaces. */
-		f->simplified = talloc_strdup(f, get_ccan_file_contents(f));
+		f->simplified = tal_strdup(f, get_ccan_file_contents(f));
 		for (i = 0, j = 0; f->simplified[i]; i++) {
 			if (cisupper(f->simplified[i]))
 				f->simplified[j++] = tolower(f->simplified[i]);

+ 3 - 3
tools/ccanlint/test/run-file_analysis.c

@@ -98,15 +98,15 @@ int main(int argc, char *argv[])
 {
 	unsigned int i;
 	struct line_info *line_info;
-	struct ccan_file *f = talloc(NULL, struct ccan_file);
+	struct ccan_file *f = tal(NULL, struct ccan_file);
 
 	plan_tests(NUM_LINES * 2 + 2 + 86);
 
 	f->num_lines = NUM_LINES;
 	f->line_info = NULL;
-	f->lines = talloc_array(f, char *, f->num_lines);
+	f->lines = tal_array(f, char *, f->num_lines);
 	for (i = 0; i < f->num_lines; i++)
-		f->lines[i] = talloc_strdup(f->lines, testfile[i].line);
+		f->lines[i] = tal_strdup(f->lines, testfile[i].line);
 	
 	line_info = get_ccan_line_info(f);
 	ok1(line_info == f->line_info);

+ 2 - 3
tools/ccanlint/tests/avoids_cpp_reserved.c

@@ -1,6 +1,5 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -51,7 +50,7 @@ static void check_headers_no_cpp(struct manifest *m,
 	if (fd < 0)
 		err(1, "Creating temporary file %s", tmpsrc);
 
-	contents = talloc_asprintf(tmpsrc,
+	contents = tal_fmt(tmpsrc,
 		   "#define alignas #DONT_USE_CPLUSPLUS_RESERVED_NAMES\n"
 		   "#define class #DONT_USE_CPLUSPLUS_RESERVED_NAMES\n"
 		   "#define constexpr #DONT_USE_CPLUSPLUS_RESERVED_NAMES\n"
@@ -93,7 +92,7 @@ static void check_headers_no_cpp(struct manifest *m,
 			   tmpobj, &cmdout)) {
 		score->score = score->total;
 	} else {
-		score->error = talloc_asprintf(score,
+		score->error = tal_fmt(score,
 				       "Main header file with C++ names:\n%s",
 				       cmdout);
 	}

+ 10 - 12
tools/ccanlint/tests/depends_accurate.c

@@ -1,8 +1,7 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
-#include <ccan/str_talloc/str_talloc.h>
+#include <ccan/take/take.h>
 #include <ccan/foreach/foreach.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -46,9 +45,9 @@ static bool check_dep_includes(struct manifest *m,
 
 	for (i = 0; lines[i]; i++) {
 		char *mod;
-		if (!strreg(f, lines[i],
-			    "^[ \t]*#[ \t]*include[ \t]*[<\"]"
-			    "(ccan/+.+)/+[^/]+\\.h", &mod))
+		if (!tal_strreg(f, lines[i],
+				"^[ \t]*#[ \t]*include[ \t]*[<\"]"
+				"(ccan/+.+)/+[^/]+\\.h", &mod))
 			continue;
 
 		if (has_dep(m, deps, used, mod))
@@ -86,10 +85,10 @@ static void check_depends_accurate(struct manifest *m,
 				 get_or_compile_info);
 	}
 
-	core_deps = talloc_array_length(deps) - 1;
-	test_deps = talloc_array_length(tdeps) - 1;
+	core_deps = tal_count(deps) - 1;
+	test_deps = tal_count(tdeps) - 1;
 
-	used = talloc_zero_array(m, bool, core_deps + test_deps + 1);
+	used = tal_arrz(m, bool, core_deps + test_deps + 1);
 
 	foreach_ptr(list, &m->c_files, &m->h_files) {
 		struct ccan_file *f;
@@ -105,10 +104,9 @@ static void check_depends_accurate(struct manifest *m,
 					 deps[i]);
 	}
 
-	/* Now append test dependencies to deps. */
-	deps = talloc_realloc(NULL, deps, char *,
-			      (core_deps + test_deps + 1) * sizeof(char *));
-	memcpy(&deps[core_deps], tdeps, test_deps * sizeof(char *));
+	/* Now remove NUL and append test dependencies to deps. */
+	deps = tal_dup(m, char *, take(deps), core_deps, test_deps + 2);
+	memcpy(deps + core_deps, tdeps, sizeof(tdeps[0]) * test_deps);
 	/* ccan/tap is given a free pass. */
 	deps[core_deps + test_deps] = (char *)"ccan/tap";
 	deps[core_deps + test_deps + 1] = NULL;

+ 11 - 13
tools/ccanlint/tests/depends_build.c

@@ -1,6 +1,5 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/foreach/foreach.h>
 #include <ccan/str/str.h>
 #include <sys/types.h>
@@ -36,18 +35,17 @@ static char *build_subdir_objs(struct manifest *m,
 	struct ccan_file *i;
 
 	list_for_each(&m->c_files, i, list) {
-		char *fullfile = talloc_asprintf(m, "%s/%s", m->dir, i->name);
+		char *fullfile = tal_fmt(m, "%s/%s", m->dir, i->name);
 		char *output;
 
 		i->compiled[ctype] = temp_file(m, "", fullfile);
 		if (!compile_object(m, fullfile, ccan_dir, compiler, flags,
 				    i->compiled[ctype], &output)) {
-			talloc_free(i->compiled[ctype]);
+			tal_free(i->compiled[ctype]);
 			i->compiled[ctype] = NULL;
-			return talloc_asprintf(m,
-					       "Dependency %s"
-					       " did not build:\n%s",
-					       m->modname, output);
+			return tal_fmt(m,
+				       "Dependency %s did not build:\n%s",
+				       m->modname, output);
 		}
 	}
 	return NULL;
@@ -90,12 +88,12 @@ static void check_depends_built(struct manifest *m,
 			errstr = build_submodule(i, cflags, COMPILE_NORMAL);
 
 			if (errstr) {
-				score->error = talloc_asprintf(score,
-							       "Dependency %s"
-							       " did not"
-							       " build:\n%s",
-							       i->modname,
-							       errstr);
+				score->error = tal_fmt(score,
+						       "Dependency %s"
+						       " did not"
+						       " build:\n%s",
+						       i->modname,
+						       errstr);
 				return;
 			}
 		}

+ 6 - 9
tools/ccanlint/tests/depends_build_without_features.c

@@ -1,6 +1,5 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
 #include <ccan/foreach/foreach.h>
 #include <sys/types.h>
@@ -32,8 +31,7 @@ static void check_depends_built_without_features(struct manifest *m,
 	struct manifest *i;
 	char *flags;
 
-	flags = talloc_asprintf(score, "%s %s", cflags,
-				REDUCE_FEATURES_FLAGS);
+	flags = tal_fmt(score, "%s %s", cflags, REDUCE_FEATURES_FLAGS);
 
 	foreach_ptr(list, &m->deps, &m->test_deps) {
 		list_for_each(list, i, list) {
@@ -41,12 +39,11 @@ static void check_depends_built_without_features(struct manifest *m,
 						       COMPILE_NOFEAT);
 
 			if (errstr) {
-				score->error = talloc_asprintf(score,
-							       "Dependency %s"
-							       " did not"
-							       " build:\n%s",
-							       i->modname,
-							       errstr);
+				score->error = tal_fmt(score,
+						       "Dependency %s"
+						       " did not build:\n%s",
+						       i->modname,
+						       errstr);
 				return;
 			}
 		}

+ 3 - 6
tools/ccanlint/tests/depends_exist.c

@@ -1,6 +1,5 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -31,14 +30,12 @@ static bool add_dep(struct manifest *m,
 {
 	struct stat st;
 	struct manifest *subm;
-	char *dir = talloc_asprintf(m, "%s/%s", ccan_dir, dep);
+	char *dir = tal_fmt(m, "%s/%s", ccan_dir, dep);
 
 	/* FIXME: get_manifest has a tendency to exit. */
 	if (stat(dir, &st) != 0) {
-		score->error
-			= talloc_asprintf(m,
-					  "Could not stat dependency %s: %s",
-					  dir, strerror(errno));
+		score->error = tal_fmt(m, "Could not stat dependency %s: %s",
+				       dir, strerror(errno));
 		return false;
 	}
 	subm = get_manifest(m, dir);

+ 80 - 76
tools/ccanlint/tests/examples_compile.c

@@ -1,7 +1,8 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
-#include <ccan/str_talloc/str_talloc.h>
+#include <ccan/tal/tal.h>
+#include <ccan/tal/str/str.h>
+#include <ccan/take/take.h>
 #include <ccan/cast/cast.h>
 #include <ccan/str/str.h>
 #include <sys/types.h>
@@ -26,8 +27,8 @@ static const char *can_run(struct manifest *m)
 
 static void add_mod(struct manifest ***deps, struct manifest *m)
 {
-	unsigned int num = talloc_get_size(*deps) / sizeof(*deps);
-	*deps = talloc_realloc(NULL, *deps, struct manifest *, num + 1);
+	unsigned int num = tal_count(*deps);
+	tal_resize(deps, num + 1);
 	(*deps)[num] = m;
 }
 
@@ -35,7 +36,7 @@ static bool have_mod(struct manifest *deps[], const char *modname)
 {
 	unsigned int i;
 
-	for (i = 0; i < talloc_get_size(deps) / sizeof(*deps); i++)
+	for (i = 0; i < tal_count(deps); i++)
 		if (strcmp(deps[i]->modname, modname) == 0)
 			return true;
 	return false;
@@ -50,8 +51,8 @@ static void add_dep(struct manifest ***deps, const char *modname)
 	if (have_mod(*deps, modname))
 		return;
 
-	m = get_manifest(*deps, talloc_asprintf(*deps, "%s/ccan/%s",
-						ccan_dir, modname));
+	m = get_manifest(*deps,
+			 tal_fmt(*deps, "%s/ccan/%s", ccan_dir, modname));
 	errstr = build_submodule(m, cflags, COMPILE_NORMAL);
 	if (errstr)
 		errx(1, "%s", errstr);
@@ -77,7 +78,7 @@ static struct manifest **get_example_deps(struct manifest *m,
 					  struct ccan_file *f)
 {
 	char **lines;
-	struct manifest **deps = talloc_array(f, struct manifest *, 0);
+	struct manifest **deps = tal_arr(f, struct manifest *, 0);
 
 	/* This one for a start. */
 	add_dep(&deps, m->modname);
@@ -85,9 +86,9 @@ static struct manifest **get_example_deps(struct manifest *m,
 	/* Other modules implied by includes. */
 	for (lines = get_ccan_file_lines(f); *lines; lines++) {
 		char *modname;
-		if (strreg(f, *lines,
-			    "^[ \t]*#[ \t]*include[ \t]*[<\"]"
-			   "ccan/+(.+)/+[^/]+\\.h", &modname)) {
+		if (tal_strreg(f, *lines,
+			       "^[ \t]*#[ \t]*include[ \t]*[<\"]"
+			       "ccan/+(.+)/+[^/]+\\.h", &modname)) {
 			if (!have_mod(deps, modname))
 				add_dep(&deps, modname);
 		}
@@ -98,29 +99,28 @@ static struct manifest **get_example_deps(struct manifest *m,
 
 static char *example_obj_list(const void *ctx, struct manifest **deps)
 {
-	char *list = talloc_strdup(ctx, "");
+	char *list = tal_strdup(ctx, "");
 	unsigned int i;
 
-	for (i = 0; i < talloc_array_length(deps); i++) {
+	for (i = 0; i < tal_count(deps); i++) {
 		if (deps[i]->compiled[COMPILE_NORMAL])
-			list = talloc_asprintf_append(list, " %s",
-						      deps[i]->compiled
-						      [COMPILE_NORMAL]);
+			tal_append_fmt(&list, " %s",
+				       deps[i]->compiled[COMPILE_NORMAL]);
 	}
 	return list;
 }
 
 static char *example_lib_list(const void *ctx, struct manifest **deps)
 {
-	char *list = talloc_strdup(ctx, "");
+	char *list = tal_strdup(ctx, "");
 	char **libs;
 	unsigned int i, j;
 
 	/* FIXME: This doesn't uniquify. */
-	for (i = 0; i < talloc_array_length(deps); i++) {
+	for (i = 0; i < tal_count(deps); i++) {
 		libs = get_libs(ctx, deps[i]->dir, NULL, get_or_compile_info);
 		for (j = 0; libs[j]; j++)
-			list = talloc_asprintf_append(list, "-l%s ", libs[j]);
+			tal_append_fmt(&list, "-l%s ", libs[j]);
 	}
 	return list;
 }
@@ -148,18 +148,20 @@ static bool compile(const void *ctx,
 	return true;
 }
 
-static char *start_main(char *ret, const char *why)
+static void start_main(char **ret, const char *why)
 {
-	return talloc_asprintf_append(ret,
+	tal_append_fmt(ret,
 	      "/* The example %s, so fake function wrapper inserted */\n"
 	      "int main(int argc, char *argv[])\n"
-	      "{\n", why);
+	       "{\n", why);
 }
 
 /* We only handle simple function definitions here. */
-static char *add_func(char *others, const char *line)
+static char *add_func(const tal_t *ctx, char *others, const char *line)
 {
 	const char *p, *end = strchr(line, '(') - 1;
+	char *use;
+
 	while (cisspace(*end)) {
 		end--;
 		if (end == line)
@@ -171,8 +173,12 @@ static char *add_func(char *others, const char *line)
 			return others;
 	}
 
-	return talloc_asprintf_append(others, "printf(\"%%p\", %.*s);\n",
-				      (unsigned)(end - p), p+1);
+	use = tal_fmt(ctx, "printf(\"%%p\", %.*s);\n",
+		      (unsigned)(end - p), p+1);
+	if (others)
+		use = tal_strcat(ctx, take(others), take(use));
+
+	return use;
 }
 
 static void strip_leading_whitespace(char **lines)
@@ -314,9 +320,9 @@ static char **combine(const void *ctx, char **lines, char **prev)
 	for (i = 0; prev[i]; i++);
 	prev_total = i;
 
-	ret = talloc_array(ctx, char *, 1 +lines_total + prev_total + 1);
-	ret[0] = talloc_asprintf(ret, "/* The example %s, thus %s */",
-				 why, reasoning);
+	ret = tal_arr(ctx, char *, 1 + lines_total + prev_total + 1);
+	ret[0] = tal_fmt(ret, "/* The example %s, thus %s */",
+			 why, reasoning);
 	memcpy(ret+1, lines, count * sizeof(ret[0]));
 	memcpy(ret+1 + count, prev, prev_total * sizeof(ret[0]));
 	memcpy(ret+1 + count + prev_total, lines + count,
@@ -327,7 +333,7 @@ static char **combine(const void *ctx, char **lines, char **prev)
 /* Only handles very simple comments. */
 static char *strip_comment(const void *ctx, const char *orig_line)
 {
-	char *p, *ret = talloc_strdup(ctx, orig_line);
+	char *p, *ret = tal_strdup(ctx, orig_line);
 
 	p = strstr(ret, "/*");
 	if (!p)
@@ -343,26 +349,26 @@ static char *mangle(struct manifest *m, char **lines)
 	bool in_function = false, fake_function = false, has_main = false;
 	unsigned int i;
 
-	ret = talloc_asprintf(m, 
-			      "/* Include header from module. */\n"
-			      "#include <ccan/%s/%s.h>\n"
-			      "/* Prepend a heap of headers. */\n"
-			      "#include <assert.h>\n"
-			      "#include <err.h>\n"
-			      "#include <errno.h>\n"
-			      "#include <fcntl.h>\n"
-			      "#include <limits.h>\n"
-			      "#include <stdbool.h>\n"
-			      "#include <stdint.h>\n"
-			      "#include <stdio.h>\n"
-			      "#include <stdlib.h>\n"
-			      "#include <string.h>\n"
-			      "#include <sys/stat.h>\n"
-			      "#include <sys/types.h>\n"
-			      "#include <unistd.h>\n",
-			      m->modname, m->basename);
-
-	ret = talloc_asprintf_append(ret, "/* Useful dummy functions. */\n"
+	ret = tal_fmt(m,
+		      "/* Include header from module. */\n"
+		      "#include <ccan/%s/%s.h>\n"
+		      "/* Prepend a heap of headers. */\n"
+		      "#include <assert.h>\n"
+		      "#include <err.h>\n"
+		      "#include <errno.h>\n"
+		      "#include <fcntl.h>\n"
+		      "#include <limits.h>\n"
+		      "#include <stdbool.h>\n"
+		      "#include <stdint.h>\n"
+		      "#include <stdio.h>\n"
+		      "#include <stdlib.h>\n"
+		      "#include <string.h>\n"
+		      "#include <sys/stat.h>\n"
+		      "#include <sys/types.h>\n"
+		      "#include <unistd.h>\n",
+		      m->modname, m->basename);
+
+	ret = tal_strcat(m, take(ret), "/* Useful dummy functions. */\n"
 				     "extern int somefunc(void);\n"
 				     "int somefunc(void) { return 0; }\n"
 				     "extern char somestring[];\n"
@@ -370,14 +376,14 @@ static char *mangle(struct manifest *m, char **lines)
 
 	if (looks_internal(lines, &why)) {
 		/* Wrap it all in main(). */
-		ret = start_main(ret, why);
+		start_main(&ret, why);
 		fake_function = true;
 		in_function = true;
 		has_main = true;
 	} else
-		ret = talloc_asprintf_append(ret,
+		tal_append_fmt(&ret,
 			     "/* The example %s, so didn't wrap in main() */\n",
-				     why);
+			       why);
 
 	/* Primitive, very primitive. */
 	for (i = 0; lines[i]; i++) {
@@ -398,7 +404,7 @@ static char *mangle(struct manifest *m, char **lines)
 				if (strncmp(line, "int main", 8) == 0)
 					has_main = true;
 				if (strncmp(line, "static", 6) == 0) {
-					use_funcs = add_func(use_funcs,
+					use_funcs = add_func(m, use_funcs,
 							     line);
 				}
 			}
@@ -408,42 +414,41 @@ static char *mangle(struct manifest *m, char **lines)
 			if (!in_function && !has_main
 			    && looks_internal(lines + i + 1, &why)) {
 				/* This implies we start a function here. */
-				ret = start_main(ret, why);
+				start_main(&ret, why);
 				has_main = true;
 				fake_function = true;
 				in_function = true;
 			}
-			ret = talloc_asprintf_append(ret,
-						     "/* ... removed */\n");
+			ret = tal_strcat(m, take(ret), "/* ... removed */\n");
 			continue;
 		}
-		ret = talloc_asprintf_append(ret, "%s\n", lines[i]);
+		ret = tal_strcat(m, take(ret), lines[i]);
+		ret = tal_strcat(m, take(ret), "\n");
 	}
 
 	if (!has_main) {
-		ret = talloc_asprintf_append(ret,
+		ret = tal_strcat(m, take(ret),
 			     "/* Need a main to link successfully. */\n"
 			     "int main(void)\n{\n");
 		fake_function = true;
 	}
 
 	if (use_funcs) {
-		ret = talloc_asprintf_append(ret,
-					     "/* Get rid of unused warnings"
-					     " by printing addresses of"
-					     " static funcs. */\n");
+		ret = tal_strcat(m, take(ret),
+				 "/* Get rid of unused warnings"
+				 " by printing addresses of"
+				 " static funcs. */\n");
 		if (!fake_function) {
-			ret = talloc_asprintf_append(ret,
-						     "int use_funcs(void);\n"
-						     "int use_funcs(void) {\n");
+			ret = tal_strcat(m, take(ret),
+					 "int use_funcs(void);\n"
+					 "int use_funcs(void) {\n");
 			fake_function = true;
 		}
-		ret = talloc_asprintf_append(ret, "	%s\n", use_funcs);
+		tal_append_fmt(&ret, "	%s\n", use_funcs);
 	}
 
 	if (fake_function)
-		ret = talloc_asprintf_append(ret, "return 0;\n"
-					     "}\n");
+		ret = tal_strcat(m, take(ret), "return 0;\n}\n");
 	return ret;
 }
 
@@ -456,12 +461,11 @@ static struct ccan_file *mangle_example(struct manifest *m,
 	struct ccan_file *f;
 
 	name = temp_file(example, ".c",
-			 talloc_asprintf(m, "%s/mangled-%s",
-					 m->dir, example->name));
+			 tal_fmt(m, "%s/mangled-%s", m->dir, example->name));
 	f = new_ccan_file(example,
-			  talloc_dirname(example, name),
-			  talloc_basename(example, name));
-	talloc_steal(f, name);
+			  tal_dirname(example, name),
+			  tal_basename(example, name));
+	tal_steal(f, name);
 
 	fd = open(f->fullname, O_WRONLY | O_CREAT | O_EXCL, 0600);
 	if (fd < 0)
@@ -473,7 +477,7 @@ static struct ccan_file *mangle_example(struct manifest *m,
 		return NULL;
 	}
 	close(fd);
-	f->contents = talloc_steal(f, contents);
+	f->contents = tal_steal(f, contents);
 	list_add(&m->mangled_examples, &f->list);
 	return f;
 }
@@ -598,7 +602,7 @@ static void build_examples(struct manifest *m,
 					" adding headers both failed";
 		} else {
 			if (num == 3) {
-				error = talloc_asprintf(score,
+				error = tal_fmt(score,
 				      "Standalone example:\n"
 				      "%s\n"
 				      "Errors: %s\n\n"
@@ -615,7 +619,7 @@ static void build_examples(struct manifest *m,
 				      get_ccan_file_contents(file[2]),
 				      err[2]);
 			} else {
-				error = talloc_asprintf(score,
+				error = tal_fmt(score,
 				      "Standalone example:\n"
 				      "%s\n"
 				      "Errors: %s\n\n"

+ 10 - 12
tools/ccanlint/tests/examples_exist.c

@@ -1,6 +1,5 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
 #include <ccan/cast/cast.h>
 #include <sys/types.h>
@@ -24,28 +23,27 @@ static char *add_example(struct manifest *m, struct ccan_file *source,
 	int fd;
 	struct ccan_file *f;
 
-	name = talloc_asprintf(m, "%s/example-%s-%s.c",
-			       talloc_dirname(m,
-					      source->fullname),
-			       source->name,
-			       example->function);
+	name = tal_fmt(m, "%s/example-%s-%s.c",
+		       tal_dirname(m, source->fullname),
+		       source->name,
+		       example->function);
 	/* example->function == 'struct foo' */
 	while (strchr(name, ' '))
 		*strchr(name, ' ') = '_';
 
 	name = temp_file(m, ".c", name);
-	f = new_ccan_file(m, talloc_dirname(m, name), talloc_basename(m, name));
-	talloc_steal(f, name);
+	f = new_ccan_file(m, tal_dirname(m, name), tal_basename(m, name));
+	tal_steal(f, name);
 	list_add_tail(&m->examples, &f->list);
 
 	fd = open(f->fullname, O_WRONLY | O_CREAT | O_EXCL, 0600);
 	if (fd < 0)
-		return talloc_asprintf(m, "Creating temporary file %s: %s",
-				       f->fullname, strerror(errno));
+		return tal_fmt(m, "Creating temporary file %s: %s",
+			       f->fullname, strerror(errno));
 
 	/* Add #line to demark where we are from, so errors are correct! */
-	linemarker = talloc_asprintf(f, "#line %i \"%s\"\n",
-				     example->srcline+2, source->fullname);
+	linemarker = tal_fmt(f, "#line %i \"%s\"\n",
+			     example->srcline+2, source->fullname);
 	write(fd, linemarker, strlen(linemarker));
 
 	for (i = 0; i < example->num_lines; i++) {

+ 0 - 1
tools/ccanlint/tests/examples_relevant.c

@@ -1,6 +1,5 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
 #include <sys/types.h>
 #include <sys/stat.h>

+ 4 - 5
tools/ccanlint/tests/examples_run.c

@@ -1,6 +1,5 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/foreach/foreach.h>
 #include <ccan/str/str.h>
 #include <ccan/cast/cast.h>
@@ -60,7 +59,7 @@ static bool scan_forv(const void *ctx,
 		for (len = 1; input[len-1]; len++) {
 			ret = scan_forv(ctx, input + len, fmt+2, &ap);
 			if (ret) {
-				*p = talloc_strndup(ctx, input, len);
+				*p = tal_strndup(ctx, input, len);
 				ret = true;
 				break;
 			}
@@ -208,12 +207,12 @@ static char *unexpected(struct ccan_file *i, const char *input,
 	bool ok;
 	unsigned int default_time = default_timeout_ms;
 
-	cmd = talloc_asprintf(i, "echo '%s' | %s %s",
-			      input, i->compiled[COMPILE_NORMAL], input);
+	cmd = tal_fmt(i, "echo '%s' | %s %s",
+		      input, i->compiled[COMPILE_NORMAL], input);
 
 	output = run_with_timeout(i, cmd, &ok, &default_time);
 	if (!ok)
-		return talloc_asprintf(i, "Exited with non-zero status\n");
+		return tal_fmt(i, "Exited with non-zero status\n");
 
 	if (exact) {
 		if (streq(output, expect) || streq(trim(output), expect))

+ 0 - 2
tools/ccanlint/tests/hash_if.c

@@ -1,8 +1,6 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
-#include <ccan/str_talloc/str_talloc.h>
 #include <ccan/foreach/foreach.h>
 #include <sys/types.h>
 #include <sys/stat.h>

+ 4 - 5
tools/ccanlint/tests/headers_idempotent.c

@@ -1,6 +1,5 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -46,13 +45,13 @@ static void handle_idem(struct manifest *m, struct score *score)
 		/* Main header gets CCAN_FOO_H, others CCAN_FOO_XXX_H */
 		if (strstarts(e->file->name, m->basename)
 		    || strlen(e->file->name) == strlen(m->basename) + 2)
-			name = talloc_asprintf(score, "CCAN_%s_H", m->modname);
+			name = tal_fmt(score, "CCAN_%s_H", m->modname);
 		else
-			name = talloc_asprintf(score, "CCAN_%s_%s",
-					       m->modname, e->file->name);
+			name = tal_fmt(score, "CCAN_%s_%s",
+				       m->modname, e->file->name);
 		fix_name(name);
 
-		q = talloc_asprintf(score,
+		q = tal_fmt(score,
 			    "Should I wrap %s in #ifndef/#define %s for you?",
 			    e->file->name, name);
 		if (!ask(q))

+ 3 - 4
tools/ccanlint/tests/info_documentation_exists.c

@@ -11,7 +11,6 @@
 #include <stdio.h>
 #include <err.h>
 #include <ccan/str/str.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/noerr/noerr.h>
 
 static void check_info_documentation_exists(struct manifest *m,
@@ -51,7 +50,7 @@ static void create_info_template_doc(struct manifest *m, struct score *score)
 		err(1, "Writing to _info.new to insert documentation");
 	}
 
-	oldcontents = talloc_grab_file(m, m->info_file->fullname, NULL);
+	oldcontents = tal_grab_file(m, m->info_file->fullname, NULL);
 	if (!oldcontents) {
 		unlink_noerr("_info.new");
 		err(1, "Reading %s", m->info_file->fullname);
@@ -93,13 +92,13 @@ static void check_info_documentation_exists(struct manifest *m,
 	if (summary && description) {
 		score->score = score->total;
 	} else if (!summary) {
-		score->error = talloc_strdup(score,
+		score->error = tal_strdup(score,
 		"_info file has no module documentation.\n\n"
 		"CCAN modules use /**-style comments for documentation: the\n"
 		"overall documentation belongs in the _info metafile.\n");
 		info_documentation_exists.handle = create_info_template_doc;
 	} else if (!description)  {
-		score->error = talloc_strdup(score,
+		score->error = tal_strdup(score,
 		"_info file has no module description.\n\n"
 		"The lines after the first summary line in the _info file\n"
 		"documentation should describe the purpose and use of the\n"

+ 4 - 3
tools/ccanlint/tests/info_exists.c

@@ -1,4 +1,6 @@
 #include <tools/ccanlint/ccanlint.h>
+#include <ccan/tal/tal.h>
+#include <ccan/tal/str/str.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -10,7 +12,6 @@
 #include <err.h>
 #include <string.h>
 #include <ccan/noerr/noerr.h>
-#include <ccan/talloc/talloc.h>
 
 static void check_has_info(struct manifest *m,
 			   unsigned int *timeleft,
@@ -21,7 +22,7 @@ static void check_has_info(struct manifest *m,
 		score->score = score->total;
 		add_info_options(m->info_file);
 	} else {
-		score->error = talloc_strdup(score,
+		score->error = tal_strdup(score,
 	"You have no _info file.\n\n"
 	"The file _info contains the metadata for a ccan package: things\n"
 	"like the dependencies, the documentation for the package as a whole\n"
@@ -63,7 +64,7 @@ static void create_info_template(struct manifest *m, struct score *score)
 	if (!ask("Should I create a template _info file for you?"))
 		return;
 
-	filename = talloc_asprintf(m, "%s/%s", m->dir, "_info");
+	filename = tal_fmt(m, "%s/%s", m->dir, "_info");
 	info = fopen(filename, "w");
 	if (!info)
 		err(1, "Trying to create a template _info in %s", filename);

+ 0 - 1
tools/ccanlint/tests/info_summary_single_line.c

@@ -1,7 +1,6 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
 #include <stdio.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
 
 static void check_info_summary_single_line(struct manifest *m,

+ 0 - 2
tools/ccanlint/tests/license_comment.c

@@ -9,9 +9,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <err.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
-#include <ccan/str_talloc/str_talloc.h>
 
 static void check_license_comment(struct manifest *m,
 				  unsigned int *timeleft, struct score *score)

+ 0 - 3
tools/ccanlint/tests/license_depends_compat.c

@@ -9,9 +9,6 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <err.h>
-#include <ccan/talloc/talloc.h>
-#include <ccan/str/str.h>
-#include <ccan/str_talloc/str_talloc.h>
 
 static void check_license_depends_compat(struct manifest *m,
 					 unsigned int *timeleft,

+ 26 - 23
tools/ccanlint/tests/license_exists.c

@@ -1,4 +1,6 @@
 #include <tools/ccanlint/ccanlint.h>
+#include <ccan/tal/tal.h>
+#include <ccan/tal/str/str.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -8,22 +10,23 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <err.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
+#include <ccan/take/take.h>
 
 /* We might need more ../ for nested modules. */
 static const char *link_prefix(struct manifest *m)
 {
-	char *prefix = talloc_strdup(m, "../../");
+	char *prefix = tal_strdup(m, "../../");
 	unsigned int i;
 
 	for (i = 0; i < strcount(m->modname, "/"); i++)
-		prefix = talloc_append_string(prefix, "../");
+		prefix = tal_strcat(m, take(prefix), "../");
 
-	return talloc_append_string(prefix, "licenses/");
+	return tal_strcat(m, take(prefix), "licenses/");
 }
 
-static const char *expected_link(const char *prefix, enum license license)
+static const char *expected_link(const tal_t *ctx,
+				 const char *prefix, enum license license)
 {
 	const char *shortname;
 
@@ -63,15 +66,15 @@ static const char *expected_link(const char *prefix, enum license license)
 		return NULL;
 	}
 
-	return talloc_append_string(talloc_strdup(prefix, prefix), shortname);
+	return tal_strcat(ctx, prefix, shortname);
 }
 
 static void handle_license_link(struct manifest *m, struct score *score)
 {
 	struct doc_section *d = find_license_tag(m);
 	const char *prefix = link_prefix(m);
-	const char *link = talloc_asprintf(m, "%s/LICENSE", m->dir);
-	const char *ldest = expected_link(prefix, m->license);
+	const char *link = tal_fmt(m, "%s/LICENSE", m->dir);
+	const char *ldest = expected_link(score, prefix, m->license);
 	char *q;
 
 	printf(
@@ -79,8 +82,8 @@ static void handle_license_link(struct manifest *m, struct score *score)
 	"LICENSE symlink into %s to avoid too many copies.\n", prefix);
 
 	/* FIXME: make ask printf-like */
-	q = talloc_asprintf(m, "Set up link to %s (license is %s)?",
-			    ldest, d->lines[0]);
+	q = tal_fmt(m, "Set up link to %s (license is %s)?",
+		    ldest, d->lines[0]);
 	if (ask(q)) {
 		if (symlink(ldest, link) != 0)
 			err(1, "Creating symlink %s -> %s", link, ldest);
@@ -94,14 +97,14 @@ static void check_has_license(struct manifest *m,
 {
 	char buf[PATH_MAX];
 	ssize_t len;
-	char *license = talloc_asprintf(m, "%s/LICENSE", m->dir);
+	char *license = tal_fmt(m, "%s/LICENSE", m->dir);
 	const char *expected;
 	struct doc_section *d;
 	const char *prefix = link_prefix(m);
 
 	d = find_license_tag(m);
 	if (!d) {
-		score->error = talloc_strdup(score, "No License: tag in _info");
+		score->error = tal_strdup(score, "No License: tag in _info");
 		return;
 	}
 
@@ -118,7 +121,7 @@ static void check_has_license(struct manifest *m,
 	/* If they have a license tag at all, we pass. */
 	score->pass = true;
 
-	expected = expected_link(prefix, m->license);
+	expected = expected_link(m, prefix, m->license);
 
 	len = readlink(license, buf, sizeof(buf));
 	if (len < 0) {
@@ -129,7 +132,7 @@ static void check_has_license(struct manifest *m,
 				return;
 			}
 			score->error
-				= talloc_asprintf(score,
+				= tal_fmt(score,
 					  "License in _info is '%s',"
 					  " expect LICENSE symlink '%s'",
 					  d->lines[0], expected);
@@ -141,7 +144,7 @@ static void check_has_license(struct manifest *m,
 				score->score = score->total;
 				return;
 			}
-			score->error = talloc_strdup(score,
+			score->error = tal_strdup(score,
 						     "LICENSE does not exist");
 			if (expected)
 				license_exists.handle = handle_license_link;
@@ -155,22 +158,22 @@ static void check_has_license(struct manifest *m,
 	buf[len] = '\0';
 
 	if (!strstarts(buf, prefix)) {
-		score->error = talloc_asprintf(score,
-					       "Expected symlink into"
-					       " %s not %s", prefix, buf);
+		score->error = tal_fmt(score,
+				       "Expected symlink into %s not %s",
+				       prefix, buf);
 		return;
 	}
 
 	if (!expected) {
-		score->error = talloc_asprintf(score,
-					  "License in _info is unknown '%s',"
-					  " but LICENSE symlink is '%s'",
-					  d->lines[0], buf);
+		score->error = tal_fmt(score,
+				       "License in _info is unknown '%s',"
+				       " but LICENSE symlink is '%s'",
+				       d->lines[0], buf);
 		return;
 	}
 
 	if (!streq(buf, expected)) {
-		score->error = talloc_asprintf(score,
+		score->error = tal_fmt(score,
 				       "Expected symlink to %s not %s",
 				       expected, buf);
 		return;

+ 0 - 2
tools/ccanlint/tests/license_file_compat.c

@@ -9,9 +9,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <err.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
-#include <ccan/str_talloc/str_talloc.h>
 
 static void check_license_file_compat(struct manifest *m,
 				      unsigned int *timeleft,

+ 3 - 4
tools/ccanlint/tests/main_header_compiles.c

@@ -1,6 +1,5 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -49,8 +48,8 @@ static void check_includes_build(struct manifest *m,
 	if (fd < 0)
 		err(1, "Creating temporary file %s", tmpsrc);
 
-	contents = talloc_asprintf(tmpsrc, "#include <ccan/%s/%s.h>\n",
-				   m->modname, m->basename);
+	contents = tal_fmt(tmpsrc, "#include <ccan/%s/%s.h>\n",
+			   m->modname, m->basename);
 	if (write(fd, contents, strlen(contents)) != strlen(contents))
 		err(1, "writing to temporary file %s", tmpsrc);
 	close(fd);
@@ -60,7 +59,7 @@ static void check_includes_build(struct manifest *m,
 		score->pass = true;
 		score->score = score->total;
 	} else {
-		score->error = talloc_asprintf(score,
+		score->error = tal_fmt(score,
 				       "#include of the main header file:\n%s",
 				       cmdout);
 	}

+ 3 - 2
tools/ccanlint/tests/main_header_exists.c

@@ -1,4 +1,6 @@
 #include <tools/ccanlint/ccanlint.h>
+#include <ccan/tal/tal.h>
+#include <ccan/tal/str/str.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -9,7 +11,6 @@
 #include <stdio.h>
 #include <err.h>
 #include <ccan/str/str.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/noerr/noerr.h>
 
 static void check_has_main_header(struct manifest *m,
@@ -25,7 +26,7 @@ static void check_has_main_header(struct manifest *m,
 			return;
 		}
 	}
-	score->error = talloc_asprintf(score,
+	score->error = tal_fmt(score,
 	"You have no %s/%s.h header file.\n\n"
 	"CCAN modules have a name, the same as the directory name.  They're\n"
 	"expected to have an interface in the header of the same name.\n",

+ 6 - 6
tools/ccanlint/tests/module_builds.c

@@ -1,7 +1,7 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
+#include <ccan/take/take.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -24,14 +24,14 @@ static const char *can_build(struct manifest *m)
 
 static char *obj_list(const struct manifest *m, enum compile_type ctype)
 {
-	char *list = talloc_strdup(m, "");
+	char *list = tal_strdup(m, "");
 	struct ccan_file *i;
 
 	/* Objects from all the C files. */
-	list_for_each(&m->c_files, i, list)
-		list = talloc_asprintf_append(list, "%s ",
-					      i->compiled[ctype]);
-
+	list_for_each(&m->c_files, i, list) {
+		list = tal_strcat(m, take(list), i->compiled[ctype]);
+		list = tal_strcat(m, take(list), " ");
+	}
 	return list;
 }
 

+ 16 - 16
tools/ccanlint/tests/module_links.c

@@ -1,7 +1,7 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
+#include <ccan/take/take.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -27,16 +27,16 @@ static char *obj_list(const struct manifest *m)
 	struct manifest *i;
 
 	if (m->compiled[COMPILE_NORMAL])
-		list = talloc_strdup(m, m->compiled[COMPILE_NORMAL]);
+		list = tal_strdup(m, m->compiled[COMPILE_NORMAL]);
 	else
-		list = talloc_strdup(m, "");
+		list = tal_strdup(m, "");
 
 	/* Other CCAN deps. */
 	list_for_each(&m->deps, i, list) {
-		if (i->compiled[COMPILE_NORMAL])
-			list = talloc_asprintf_append(list, " %s",
-						      i->compiled
-						      [COMPILE_NORMAL]);
+		if (!i->compiled[COMPILE_NORMAL])
+			continue;
+		list = tal_strcat(m, take(list), " ");
+		list = tal_strcat(m, take(list), i->compiled[COMPILE_NORMAL]);
 	}
 	return list;
 }
@@ -45,11 +45,11 @@ static char *lib_list(const struct manifest *m)
 {
 	unsigned int i;
 	char **libs;
-	char *ret = talloc_strdup(m, "");
+	char *ret = tal_strdup(m, "");
 
 	libs = get_libs(m, m->dir, "depends", get_or_compile_info);
 	for (i = 0; libs[i]; i++)
-		ret = talloc_asprintf_append(ret, "-l%s ", libs[i]);
+		tal_append_fmt(&ret, "-l%s ", libs[i]);
 	return ret;
 }
 
@@ -66,13 +66,13 @@ static void check_use_build(struct manifest *m,
 	if (fd < 0)
 		err(1, "Creating temporary file %s", tmpfile);
 
-	contents = talloc_asprintf(tmpfile,
-				   "#include <ccan/%s/%s.h>\n"
-				   "int main(void)\n"
-				   "{\n"
-				   "	return 0;\n"
-				   "}\n",
-				   m->modname, m->basename);
+	contents = tal_fmt(tmpfile,
+			   "#include <ccan/%s/%s.h>\n"
+			   "int main(void)\n"
+			   "{\n"
+			   "	return 0;\n"
+			   "}\n",
+			   m->modname, m->basename);
 	if (write(fd, contents, strlen(contents)) != strlen(contents))
 		err(1, "Failure writing to temporary file %s", tmpfile);
 	close(fd);

+ 6 - 6
tools/ccanlint/tests/no_trailing_whitespace.c

@@ -1,11 +1,11 @@
 /* Trailing whitespace test.  Almost embarrassing, but trivial. */
 #include <tools/ccanlint/ccanlint.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/foreach/foreach.h>
 #include <ccan/str/str.h>
+#include <ccan/tal/str/str.h>
 
 /* FIXME: only print full analysis if verbose >= 2.  */
-static char *get_trailing_whitespace(const char *line)
+static char *get_trailing_whitespace(const tal_t *ctx, const char *line)
 {
 	const char *e = strchr(line, 0);
 	while (e>line && (e[-1]==' ' || e[-1]=='\t'))
@@ -16,9 +16,8 @@ static char *get_trailing_whitespace(const char *line)
 		return NULL; //the line only consists of spaces
 
 	if (strlen(line) > 20)
-		return talloc_asprintf(line, "...'%s'",
-				       line + strlen(line) - 20);
-	return talloc_asprintf(line, "'%s'", line);
+		return tal_fmt(ctx, "...'%s'", line + strlen(line) - 20);
+	return tal_fmt(ctx, "'%s'", line);
 }
 
 static void check_trailing_whitespace(struct manifest *m,
@@ -36,7 +35,8 @@ static void check_trailing_whitespace(struct manifest *m,
 		list_for_each(list, f, list) {
 			char **lines = get_ccan_file_lines(f);
 			for (i = 0; i < f->num_lines; i++) {
-				char *err = get_trailing_whitespace(lines[i]);
+				char *err = get_trailing_whitespace(score,
+								    lines[i]);
 				if (err)
 					score_file_error(score, f, i+1,
 							 "%s", err);

+ 2 - 3
tools/ccanlint/tests/objects_build.c

@@ -1,6 +1,5 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -36,12 +35,12 @@ void build_objects(struct manifest *m,
 
 	list_for_each(&m->c_files, i, list) {
 		char *output;
-		char *fullfile = talloc_asprintf(m, "%s/%s", m->dir, i->name);
+		char *fullfile = tal_fmt(m, "%s/%s", m->dir, i->name);
 
 		i->compiled[ctype] = temp_file(m, "", fullfile);
 		if (!compile_object(score, fullfile, ccan_dir, compiler, flags,
 				    i->compiled[ctype], &output)) {
-			talloc_free(i->compiled[ctype]);
+			tal_free(i->compiled[ctype]);
 			score_file_error(score, i, 0,
 					 "Compiling object files:\n%s",
 					 output);

+ 4 - 6
tools/ccanlint/tests/objects_build_with_stringchecks.c

@@ -1,8 +1,6 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
-#include <ccan/str_talloc/str_talloc.h>
 #include <ccan/foreach/foreach.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -26,7 +24,7 @@ static const char *uses_stringfuncs(struct manifest *m)
 		char *match;
 
 		list_for_each(list, i, list) {
-			if (strreg(m, get_ccan_file_contents(i),
+			if (tal_strreg(m, get_ccan_file_contents(i),
 				   "(isalnum|isalpha|isascii|isblank|iscntrl"
 				   "|isdigit|isgraph|islower|isprint|ispunct"
 				   "|isspace|isupper|isxdigit"
@@ -103,7 +101,7 @@ static void build_objects_with_stringchecks(struct manifest *m,
 	int tmpfd;
 
 	/* FIXME:: We need -I so local #includes work outside normal dir. */
-	flags = talloc_asprintf(score, "-I%s %s", m->dir, cflags);
+	flags = tal_fmt(score, "-I%s %s", m->dir, cflags);
 
 	/* Won't work into macros, but will get inline functions. */
 	if (list_empty(&m->c_files)) {
@@ -111,8 +109,8 @@ static void build_objects_with_stringchecks(struct manifest *m,
 		i = get_main_header(m);
 		tmp = temp_file(score, ".c", i->fullname);
 		tmpfd = start_file(tmp);
-		line = talloc_asprintf(score, "#include <ccan/%s/%s.h>\n",
-				       m->modname, m->basename);
+		line = tal_fmt(score, "#include <ccan/%s/%s.h>\n",
+			       m->modname, m->basename);
 		write_str(tmpfd, line);
 		close(tmpfd);
 		test_compile(score, i, tmp, flags, &errors, &warnings);

+ 3 - 3
tools/ccanlint/tests/objects_build_without_features.c

@@ -1,5 +1,5 @@
 #include <tools/ccanlint/ccanlint.h>
-#include <ccan/talloc/talloc.h>
+#include <ccan/tal/str/str.h>
 #include "reduce_features.h"
 #include "build.h"
 
@@ -7,8 +7,8 @@ static void check_objs_build_without_features(struct manifest *m,
 					      unsigned int *timeleft,
 					      struct score *score)
 {
-	const char *flags = talloc_asprintf(score, "%s %s",
-					    REDUCE_FEATURES_FLAGS, cflags);
+	const char *flags = tal_fmt(score, "%s %s",
+				    REDUCE_FEATURES_FLAGS, cflags);
 	build_objects(m, score, flags, COMPILE_NOFEAT);
 }
 

+ 7 - 9
tools/ccanlint/tests/reduce_features.c

@@ -2,9 +2,7 @@
 #include <tools/tools.h>
 #include <ccan/htable/htable_type.h>
 #include <ccan/foreach/foreach.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
-#include <ccan/str_talloc/str_talloc.h>
 #include <ccan/hash/hash.h>
 #include <ccan/read_write_all/read_write_all.h>
 #include <errno.h>
@@ -20,7 +18,7 @@ bool features_were_reduced;
 static const char *can_run(struct manifest *m)
 {
 	if (!config_header)
-		return talloc_strdup(m, "Could not read config.h");
+		return tal_strdup(m, "Could not read config.h");
 	return NULL;
 }
 
@@ -103,11 +101,12 @@ static struct htable_option *get_used_options(struct manifest *m)
 
 static struct htable_option *get_config_options(struct manifest *m)
 {
-	const char **lines = (const char **)strsplit(m, config_header, "\n");
+	const char **lines = (const char **)tal_strsplit(m, config_header, "\n",
+							 STR_EMPTY_OK);
 	unsigned int i;
 	struct htable_option *opts = htable_option_new();
 
-	for (i = 0; i < talloc_array_length(lines) - 1; i++) {
+	for (i = 0; i < tal_count(lines) - 1; i++) {
 		char *sym;
 
 		if (!get_token(&lines[i], "#"))
@@ -166,13 +165,12 @@ static void do_reduce_features(struct manifest *m,
 		return;
 
 	/* Now make our own config.h variant, with our own options. */
-	hdr = talloc_strdup(m, "/* Modified by reduce_features */\n");
-	hdr = talloc_append_string(hdr, config_header);
+	hdr = tal_strcat(m, "/* Modified by reduce_features */\n",
+			 config_header);
 	for (sym = htable_option_first(options, &i);
 	     sym;
 	     sym = htable_option_next(options, &i)) {
-		hdr = talloc_asprintf_append
-			(hdr, "#undef %s\n#define %s 0\n", sym, sym);
+		tal_append_fmt(&hdr, "#undef %s\n#define %s 0\n", sym, sym);
 	}
 	if (mkdir("reduced-features", 0700) != 0 && errno != EEXIST)
 		err(1, "Creating reduced-features directory");

+ 17 - 22
tools/ccanlint/tests/tests_compile.c

@@ -1,6 +1,5 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
 #include <ccan/foreach/foreach.h>
 #include <sys/types.h>
@@ -27,33 +26,29 @@ static const char *can_build(struct manifest *m)
 char *test_obj_list(const struct manifest *m, bool link_with_module,
 		    enum compile_type ctype, enum compile_type own_ctype)
 {
-	char *list = talloc_strdup(m, "");
+	char *list = tal_strdup(m, "");
 	struct ccan_file *i;
 	struct manifest *subm;
 
 	/* Objects from any other C files. */
 	list_for_each(&m->other_test_c_files, i, list)
-		list = talloc_asprintf_append(list, " %s",
-					      i->compiled[ctype]);
+		tal_append_fmt(&list, " %s", i->compiled[ctype]);
 
 	/* Our own object files. */
 	if (link_with_module)
 		list_for_each(&m->c_files, i, list)
-			list = talloc_asprintf_append(list, " %s",
-						      i->compiled[own_ctype]);
+			tal_append_fmt(&list, " %s", i->compiled[own_ctype]);
 
 	/* Other ccan modules (normal depends). */
 	list_for_each(&m->deps, subm, list) {
 		if (subm->compiled[ctype])
-			list = talloc_asprintf_append(list, " %s",
-						      subm->compiled[ctype]);
+			tal_append_fmt(&list, " %s", subm->compiled[ctype]);
 	}
 
 	/* Other ccan modules (test depends). */
 	list_for_each(&m->test_deps, subm, list) {
 		if (subm->compiled[ctype])
-			list = talloc_asprintf_append(list, " %s",
-						      subm->compiled[ctype]);
+			tal_append_fmt(&list, " %s", subm->compiled[ctype]);
 	}
 
 	return list;
@@ -63,11 +58,11 @@ char *test_lib_list(const struct manifest *m, enum compile_type ctype)
 {
 	unsigned int i;
 	char **libs;
-	char *ret = talloc_strdup(m, "");
+	char *ret = tal_strdup(m, "");
 
 	libs = get_libs(m, m->dir, "testdepends", get_or_compile_info);
 	for (i = 0; libs[i]; i++)
-		ret = talloc_asprintf_append(ret, "-l%s ", libs[i]);
+		tal_append_fmt(&ret, "-l%s ", libs[i]);
 	return ret;
 }
 
@@ -81,11 +76,11 @@ static bool compile(const void *ctx,
 {
 	char *fname, *flags;
 
-	flags = talloc_asprintf(ctx, "%s%s%s",
-				fail ? "-DFAIL " : "",
-				cflags,
-				ctype == COMPILE_NOFEAT
-				? " "REDUCE_FEATURES_FLAGS : "");
+	flags = tal_fmt(ctx, "%s%s%s",
+			fail ? "-DFAIL " : "",
+			cflags,
+			ctype == COMPILE_NOFEAT
+			? " "REDUCE_FEATURES_FLAGS : "");
 
 	fname = temp_file(ctx, "", file->fullname);
 	if (!compile_and_link(ctx, file->fullname, ccan_dir,
@@ -93,7 +88,7 @@ static bool compile(const void *ctx,
 					    ctype, ctype),
 			      compiler, flags, test_lib_list(m, ctype), fname,
 			      output)) {
-		talloc_free(fname);
+		tal_free(fname);
 		return false;
 	}
 
@@ -111,10 +106,10 @@ static void compile_async(const void *ctx,
 	char *flags;
 
 	file->compiled[ctype] = temp_file(ctx, "", file->fullname);
-	flags = talloc_asprintf(ctx, "%s%s",
-				cflags,
-				ctype == COMPILE_NOFEAT
-				? " "REDUCE_FEATURES_FLAGS : "");
+	flags = tal_fmt(ctx, "%s%s",
+			cflags,
+			ctype == COMPILE_NOFEAT
+			? " "REDUCE_FEATURES_FLAGS : "");
 
 	compile_and_link_async(file, time_ms, file->fullname, ccan_dir,
 			       test_obj_list(m, link_with_module, ctype, ctype),

+ 4 - 5
tools/ccanlint/tests/tests_compile_coverage.c

@@ -1,6 +1,5 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
 #include <ccan/foreach/foreach.h>
 #include <sys/types.h>
@@ -25,7 +24,7 @@ static const char *can_run_coverage(struct manifest *m)
 	char *output;
 
 	if (!run_command(m, &timeleft, &output, "gcov -h"))
-		return talloc_asprintf(m, "No gcov support: %s", output);
+		return tal_fmt(m, "No gcov support: %s", output);
 	return NULL;
 #else
 	return "No coverage support for this compiler";
@@ -38,7 +37,7 @@ static void cov_compile(const void *ctx,
 			struct ccan_file *file,
 			bool link_with_module)
 {
-	char *flags = talloc_asprintf(ctx, "%s %s", cflags, COVERAGE_CFLAGS);
+	char *flags = tal_fmt(ctx, "%s %s", cflags, COVERAGE_CFLAGS);
 
 	file->compiled[COMPILE_COVERAGE] = temp_file(ctx, "", file->fullname);
 	compile_and_link_async(file, time_ms, file->fullname, ccan_dir,
@@ -59,13 +58,13 @@ static void do_compile_coverage_tests(struct manifest *m,
 	struct ccan_file *i;
 	struct list_head *h;
 	bool ok;
-	char *f = talloc_asprintf(score, "%s %s", cflags, COVERAGE_CFLAGS);
+	char *f = tal_fmt(score, "%s %s", cflags, COVERAGE_CFLAGS);
 
 	/* For API tests, we need coverage version of module. */
 	if (!list_empty(&m->api_tests)) {
 		build_objects(m, score, f, COMPILE_COVERAGE);
 		if (!score->pass) {
-			score->error = talloc_strdup(score,
+			score->error = tal_strdup(score,
 						     "Failed to compile module objects with coverage");
 			return;
 		}

+ 11 - 15
tools/ccanlint/tests/tests_coverage.c

@@ -1,7 +1,5 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
-#include <ccan/str_talloc/str_talloc.h>
 #include <ccan/str/str.h>
 #include <ccan/foreach/foreach.h>
 #include <sys/types.h>
@@ -53,7 +51,7 @@ static unsigned int score_coverage(float covered, unsigned total)
 static void analyze_coverage(struct manifest *m, bool full_gcov,
 			     const char *output, struct score *score)
 {
-	char **lines = strsplit(score, output, "\n");
+	char **lines = tal_strsplit(score, output, "\n", STR_EMPTY_OK);
 	float covered_lines = 0.0;
 	unsigned int i, total_lines = 0;
 	bool lines_matter = false;
@@ -100,11 +98,11 @@ static void analyze_coverage(struct manifest *m, bool full_gcov,
 			apostrophe = strchr(filename, '\'');
 			*apostrophe = '\0';
 			if (lines_matter) {
-				file = talloc_grab_file(score, filename, NULL);
+				file = tal_grab_file(score, filename, NULL);
 				if (!file) {
-					score->error = talloc_asprintf(score,
-							    "Reading %s",
-							    filename);
+					score->error = tal_fmt(score,
+							       "Reading %s",
+							       filename);
 					return;
 				}
 				printf("%s", file);
@@ -144,19 +142,18 @@ static void do_run_coverage_tests(struct manifest *m,
 	bool ran_some = false;
 
 	/* This tells gcov where we put those .gcno files. */
-	outdir = talloc_dirname(score,
+	outdir = tal_dirname(score,
 				m->info_file->compiled[COMPILE_NORMAL]);
-	covcmd = talloc_asprintf(m, "gcov %s -o %s",
-				 full_gcov ? "" : "-n",
-				 outdir);
+	covcmd = tal_fmt(m, "gcov %s -o %s",
+			 full_gcov ? "" : "-n",
+			 outdir);
 
 	/* Run them all. */
 	foreach_ptr(list, &m->run_tests, &m->api_tests) {
 		list_for_each(list, i, list) {
 			if (run_command(score, timeleft, &cmdout,
 					"%s", i->compiled[COMPILE_COVERAGE])) {
-				covcmd = talloc_asprintf_append(covcmd, " %s",
-								i->fullname);
+				tal_append_fmt(&covcmd, " %s", i->fullname);
 			} else {
 				score_file_error(score, i, 0,
 						 "Running test with coverage"
@@ -176,8 +173,7 @@ static void do_run_coverage_tests(struct manifest *m,
 
 	/* Now run gcov: we want output even if it succeeds. */
 	if (!run_command(score, timeleft, &cmdout, "%s", covcmd)) {
-		score->error = talloc_asprintf(score, "Running gcov: %s",
-					       cmdout);
+		score->error = tal_fmt(score, "Running gcov: %s", cmdout);
 		return;
 	}
 

+ 7 - 8
tools/ccanlint/tests/tests_exist.c

@@ -1,4 +1,5 @@
 #include <tools/ccanlint/ccanlint.h>
+#include <ccan/tal/str/str.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -8,7 +9,6 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <err.h>
-#include <ccan/talloc/talloc.h>
 
 static void check_tests_exist(struct manifest *m,
 			      unsigned int *timeleft, struct score *score);
@@ -25,7 +25,7 @@ static void handle_no_tests(struct manifest *m, struct score *score)
 {
 	FILE *run;
 	struct ccan_file *i;
-	char *test_dir = talloc_asprintf(m, "%s/test", m->dir), *run_file;
+	char *test_dir = tal_fmt(m, "%s/test", m->dir), *run_file;
 
 	printf(
 	"CCAN modules have a directory called test/ which contains tests.\n"
@@ -64,7 +64,7 @@ static void handle_no_tests(struct manifest *m, struct score *score)
 			err(1, "Creating test/ directory");
 	}
 
-	run_file = talloc_asprintf(test_dir, "%s/run.c", test_dir);
+	run_file = tal_fmt(test_dir, "%s/run.c", test_dir);
 	run = fopen(run_file, "w");
 	if (!run)
 		err(1, "Trying to create a test/run.c");
@@ -106,10 +106,10 @@ static void check_tests_exist(struct manifest *m,
 			    unsigned int *timeleft, struct score *score)
 {
 	struct stat st;
-	char *test_dir = talloc_asprintf(m, "%s/test", m->dir);
+	char *test_dir = tal_fmt(m, "%s/test", m->dir);
 
 	if (lstat(test_dir, &st) != 0) {
-		score->error = talloc_strdup(score, "No test directory");
+		score->error = tal_strdup(score, "No test directory");
 		if (errno != ENOENT)
 			err(1, "statting %s", test_dir);
 		tests_exist.handle = handle_no_tests;
@@ -119,7 +119,7 @@ static void check_tests_exist(struct manifest *m,
 	}
 
 	if (!S_ISDIR(st.st_mode)) {
-		score->error = talloc_strdup(score, "test is not a directory");
+		score->error = tal_strdup(score, "test is not a directory");
 		return;
 	}
 
@@ -127,8 +127,7 @@ static void check_tests_exist(struct manifest *m,
 	    && list_empty(&m->run_tests)
 	    && list_empty(&m->compile_ok_tests)
 	    && list_empty(&m->compile_fail_tests)) {
-		score->error = talloc_strdup(score,
-					     "No tests in test directory");
+		score->error = tal_strdup(score, "No tests in test directory");
 		tests_exist.handle = handle_no_tests;
 		return;
 	}

+ 1 - 3
tools/ccanlint/tests/tests_helpers_compile.c

@@ -1,6 +1,5 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -97,8 +96,7 @@ static void do_compile_test_helpers_without_features(struct manifest *m,
 {
 	char *flags;
 
-	flags = talloc_asprintf(score, "%s %s", cflags,
-				REDUCE_FEATURES_FLAGS);
+	flags = tal_fmt(score, "%s %s", cflags, REDUCE_FEATURES_FLAGS);
 
 	compile_test_helpers(m, timeleft, score, flags, COMPILE_NOFEAT);
 }

+ 7 - 7
tools/ccanlint/tests/tests_pass.c

@@ -1,6 +1,6 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
+#include <ccan/take/take.h>
 #include <ccan/str/str.h>
 #include <ccan/foreach/foreach.h>
 #include <sys/types.h>
@@ -36,12 +36,12 @@ static const char *can_run(struct manifest *m)
 static const char *concat(struct score *score, char *bits[])
 {
 	unsigned int i;
-	char *ret = talloc_strdup(score, "");
+	char *ret = tal_strdup(score, "");
 
 	for (i = 0; bits[i]; i++) {
 		if (i)
-			ret = talloc_append_string(ret, " ");
-		ret = talloc_append_string(ret, bits[i]);
+			ret = tal_strcat(score, take(ret), " ");
+		ret = tal_strcat(score, take(ret), bits[i]);
 	}
 	return ret;
 }
@@ -60,7 +60,7 @@ static void run_test(void *ctx,
 			/* FIXME: Valgrind's output sucks.  XML is
 			 * unreadable by humans *and* doesn't support
 			 * children reporting. */
-			i->valgrind_log = talloc_asprintf(m,
+			i->valgrind_log = tal_fmt(m,
 					  "%s.valgrind-log",
 					  i->compiled[COMPILE_NORMAL]);
 
@@ -126,8 +126,8 @@ static void run_under_debugger(struct manifest *m, struct score *score)
 	if (!ask("Should I run the first failing test under the debugger?"))
 		return;
 
-	command = talloc_asprintf(m, "gdb -ex 'break tap.c:139' -ex 'run' %s",
-				  first->file->compiled[COMPILE_NORMAL]);
+	command = tal_fmt(m, "gdb -ex 'break tap.c:139' -ex 'run' %s",
+			  first->file->compiled[COMPILE_NORMAL]);
 	if (system(command))
 		doesnt_matter();
 }

+ 33 - 33
tools/ccanlint/tests/tests_pass_valgrind.c

@@ -1,9 +1,8 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
+#include <ccan/take/take.h>
 #include <ccan/foreach/foreach.h>
-#include <ccan/str_talloc/str_talloc.h>
 #include "tests_pass.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -21,7 +20,7 @@
 static const char *can_run_vg(struct manifest *m)
 {
 	if (!do_valgrind)
-		return talloc_asprintf(m, "No valgrind support");
+		return tal_fmt(m, "No valgrind support");
 	return NULL;
 }
 
@@ -61,35 +60,34 @@ static bool blank_line(const char *line)
 static char **extract_matching(const char *prefix, char *lines[])
 {
 	unsigned int i, num_ret = 0;
-	char **ret = talloc_array(lines, char *, talloc_array_length(lines));
+	char **ret = tal_arr(lines, char *, tal_count(lines));
 
-	for (i = 0; i < talloc_array_length(lines) - 1; i++) {
+	for (i = 0; i < tal_count(lines) - 1; i++) {
 		if (strstarts(lines[i], prefix)) {
-			ret[num_ret++] = talloc_steal(ret, lines[i]);
+			ret[num_ret++] = tal_strdup(ret, lines[i]);
 			lines[i] = (char *)"";
 		}
 	}
 	ret[num_ret++] = NULL;
 
-	/* Make sure length is correct! */
-	return talloc_realloc(NULL, ret, char *, num_ret);
+	/* Make sure tal_count is correct! */
+	tal_resize(&ret, num_ret);
+	return ret;
 }
 
 static char *get_leaks(char *lines[], char **errs)
 {
-	char *leaks = talloc_strdup(lines, "");
+	char *leaks = tal_strdup(lines, "");
 	unsigned int i;
 
-	for (i = 0; i < talloc_array_length(lines) - 1; i++) {
+	for (i = 0; i < tal_count(lines) - 1; i++) {
 		if (strstr(lines[i], " lost ")) {
 			/* A leak... */
 			if (strstr(lines[i], " definitely lost ")) {
 				/* Definite leak, report. */
 				while (lines[i] && !blank_line(lines[i])) {
-					leaks = talloc_append_string(leaks,
-								     lines[i]);
-					leaks = talloc_append_string(leaks,
-								     "\n");
+					tal_append_fmt(&leaks, "%s\n",
+						       lines[i]);
 					i++;
 				}
 			} else
@@ -99,8 +97,10 @@ static char *get_leaks(char *lines[], char **errs)
 		} else {
 			/* A real error. */
 			while (lines[i] && !blank_line(lines[i])) {
-				*errs = talloc_append_string(*errs, lines[i]);
-				*errs = talloc_append_string(*errs, "\n");
+				if (!*errs)
+					*errs = tal_fmt(NULL, "%s\n", lines[i]);
+				else
+					tal_append_fmt(errs, "%s\n", lines[i]);
 				i++;
 			}
 		}
@@ -111,12 +111,12 @@ static char *get_leaks(char *lines[], char **errs)
 /* Returns leaks, and sets errs[] */
 static char *analyze_output(const char *output, char **errs)
 {
-	char *leaks = talloc_strdup(output, "");
+	char *leaks = tal_strdup(output, "");
 	unsigned int i;
-	char **lines = strsplit(output, output, "\n");
+	char **lines = tal_strsplit(output, output, "\n", STR_EMPTY_OK);
 
-	*errs = talloc_strdup(output, "");
-	for (i = 0; i < talloc_array_length(lines) - 1; i++) {
+	*errs = tal_strdup(output, "");
+	for (i = 0; i < tal_count(lines) - 1; i++) {
 		unsigned int preflen = strspn(lines[i], "=0123456789");
 		char *prefix, **sublines;
 
@@ -124,18 +124,19 @@ static char *analyze_output(const char *output, char **errs)
 		if (preflen == 0)
 			continue;
 
-		prefix = talloc_strndup(output, lines[i], preflen);
+		prefix = tal_strndup(output, lines[i], preflen);
 		sublines = extract_matching(prefix, lines);
 
-		leaks = talloc_append_string(leaks, get_leaks(sublines, errs));
+		leaks = tal_strcat(output, take(leaks),
+				   take(get_leaks(sublines, errs)));
 	}
 
 	if (!leaks[0]) {
-		talloc_free(leaks);
+		tal_free(leaks);
 		leaks = NULL;
 	}
 	if (!(*errs)[0]) {
-		talloc_free(*errs);
+		tal_free(*errs);
 		*errs = NULL;
 	}
 	return leaks;
@@ -144,12 +145,12 @@ static char *analyze_output(const char *output, char **errs)
 static const char *concat(struct score *score, char *bits[])
 {
 	unsigned int i;
-	char *ret = talloc_strdup(score, "");
+	char *ret = tal_strdup(score, "");
 
 	for (i = 0; bits[i]; i++) {
 		if (i)
-			ret = talloc_append_string(ret, " ");
-		ret = talloc_append_string(ret, bits[i]);
+			ret = tal_strcat(score, take(ret), " ");
+		ret = tal_strcat(score, take(ret), bits[i]);
 	}
 	return ret;
 }
@@ -179,7 +180,7 @@ static void do_run_tests_vg(struct manifest *m,
 				continue;
 			}
 
-			output = talloc_grab_file(i, i->valgrind_log, NULL);
+			output = tal_grab_file(i, i->valgrind_log, NULL);
 			/* No valgrind errors? */
 			if (!output || output[0] == '\0') {
 				err = NULL;
@@ -249,11 +250,10 @@ static void run_under_debugger_vg(struct manifest *m, struct score *score)
 		return;
 
 	first = list_top(&score->per_file_errors, struct file_error, list);
-	command = talloc_asprintf(m, "valgrind --leak-check=full --db-attach=yes%s %s",
-				  concat(score,
-					 per_file_options(&tests_pass_valgrind,
-							  first->file)),
-				  first->file->compiled[COMPILE_NORMAL]);
+	command = tal_fmt(m, "valgrind --leak-check=full --db-attach=yes%s %s",
+			  concat(score, per_file_options(&tests_pass_valgrind,
+							 first->file)),
+			  first->file->compiled[COMPILE_NORMAL]);
 	if (system(command))
 		doesnt_matter();
 }

+ 2 - 4
tools/ccanlint/tests/tests_pass_without_features.c

@@ -1,6 +1,5 @@
 #include <tools/ccanlint/ccanlint.h>
 #include <tools/tools.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
 #include <ccan/foreach/foreach.h>
 #include <sys/types.h>
@@ -55,9 +54,8 @@ static void run_under_debugger(struct manifest *m, struct score *score)
 	if (!ask("Should I run the first failing test under the debugger?"))
 		return;
 
-	command = talloc_asprintf(m, "gdb -ex 'break tap.c:139' -ex 'run' %s",
-				  first->file->compiled
-				  [COMPILE_NOFEAT]);
+	command = tal_fmt(m, "gdb -ex 'break tap.c:139' -ex 'run' %s",
+			  first->file->compiled[COMPILE_NOFEAT]);
 	if (system(command))
 		doesnt_matter();
 }

+ 1 - 2
tools/compile.c

@@ -1,5 +1,4 @@
 #include "tools.h"
-#include <ccan/talloc/talloc.h>
 #include <stdlib.h>
 
 bool compile_verbose = false;
@@ -16,7 +15,7 @@ char *link_objects(const void *ctx, const char *basename,
 	if (run_command(ctx, NULL, errmsg, "ld -r -o %s %s", file, objs))
 		return file;
 
-	talloc_free(file);
+	tal_free(file);
 	return NULL;
 }
 

+ 39 - 41
tools/depends.c

@@ -1,6 +1,4 @@
 #include <ccan/str/str.h>
-#include <ccan/talloc/talloc.h>
-#include <ccan/str_talloc/str_talloc.h>
 #include <ccan/read_write_all/read_write_all.h>
 #include <ccan/rbuf/rbuf.h>
 #include <ccan/compiler/compiler.h>
@@ -22,7 +20,7 @@ lines_from_cmd(const void *ctx, const char *format, ...)
 	struct rbuf in;
 
 	va_start(ap, format);
-	cmd = talloc_vasprintf(ctx, format, ap);
+	cmd = tal_vfmt(ctx, format, ap);
 	va_end(ap);
 
 	p = popen(cmd, "r");
@@ -30,12 +28,12 @@ lines_from_cmd(const void *ctx, const char *format, ...)
 		err(1, "Executing '%s'", cmd);
 
 	/* FIXME: Use rbuf_read_str(&in, '\n') rather than strsplit! */
-	rbuf_init(&in, fileno(p), talloc_array(ctx, char, 4096), 4096);
-	if (!rbuf_read_str(&in, 0, do_talloc_realloc) && errno)
+	rbuf_init(&in, fileno(p), tal_arr(ctx, char, 0), 0);
+	if (!rbuf_read_str(&in, 0, do_tal_realloc) && errno)
 		err(1, "Reading from '%s'", cmd);
 	pclose(p);
 
-	return strsplit(ctx, in.buf, "\n");
+	return tal_strsplit(ctx, in.buf, "\n", STR_EMPTY_OK);
 }
 
 /* Be careful about trying to compile over running programs (parallel make).
@@ -47,8 +45,7 @@ char *compile_info(const void *ctx, const char *dir)
 	int fd;
 
 	/* Copy it to a file with proper .c suffix. */
-	info = talloc_grab_file(ctx, talloc_asprintf(ctx, "%s/_info", dir),
-				&len);
+	info = tal_grab_file(ctx, tal_fmt(ctx, "%s/_info", dir), &len);
 	if (!info)
 		return NULL;
 
@@ -79,13 +76,13 @@ static char **get_one_deps(const void *ctx, const char *dir, const char *style,
 	if (!infofile)
 		return NULL;
 
-	cmd = talloc_asprintf(ctx, "%s %s", infofile, style);
+	cmd = tal_fmt(ctx, "%s %s", infofile, style);
 	deps = lines_from_cmd(cmd, "%s", cmd);
 	if (!deps) {
 		/* You must understand depends, maybe not testdepends. */
 		if (streq(style, "depends"))
 			err(1, "Could not run '%s'", cmd);
-		deps = talloc(ctx, char *);
+		deps = tal(ctx, char *);
 		deps[0] = NULL;
 	}
 	return deps;
@@ -95,7 +92,7 @@ static char **get_one_deps(const void *ctx, const char *dir, const char *style,
 static char *replace(const void *ctx, const char *src,
 		     const char *from, const char *to)
 {
-	char *ret = talloc_strdup(ctx, "");
+	char *ret = tal_strdup(ctx, "");
 	unsigned int rlen, len, add;
 
 	rlen = len = 0;
@@ -106,7 +103,7 @@ static char *replace(const void *ctx, const char *src,
 		else
 			add = next - (src+len);
 
-		ret = talloc_realloc(ctx, ret, char, rlen + add + strlen(to)+1);
+		tal_resize(&ret, rlen + add + strlen(to)+1);
 		memcpy(ret+rlen, src+len, add);
 		if (!next)
 			return ret;
@@ -128,15 +125,16 @@ static char **get_one_safe_deps(const void *ctx,
 	unsigned int i, n;
 	bool correct_style = false;
 
-	fname = talloc_asprintf(ctx, "%s/_info", dir);
-	raw = talloc_grab_file(fname, fname, NULL);
+	fname = tal_fmt(ctx, "%s/_info", dir);
+	raw = tal_grab_file(fname, fname, NULL);
 	if (!raw)
 		errx(1, "Could not open %s", fname);
 
 	/* Replace \n by actual line breaks, and split it. */
-	lines = strsplit(raw, replace(raw, raw, "\\n", "\n"), "\n");
+	lines = tal_strsplit(raw, replace(raw, raw, "\\n", "\n"), "\n",
+			     STR_EMPTY_OK);
 
-	deps = talloc_array(ctx, char *, talloc_array_length(lines));
+	deps = tal_arr(ctx, char *, tal_count(lines));
 
 	for (n = i = 0; lines[i]; i++) {
 		char *str;
@@ -167,13 +165,14 @@ static char **get_one_safe_deps(const void *ctx,
 		len = strspn(str, "/abcdefghijklmnopqrstuvxwyz12345678980_");
 		if (len == 5)
 			continue;
-		deps[n++] = talloc_strndup(deps, str, len);
+		deps[n++] = tal_strndup(deps, str, len);
 	}
 	deps[n] = NULL;
-	talloc_free(fname);
+	tal_free(fname);
 
-	/* Make sure talloc_array_length() works */
-	return talloc_realloc(NULL, deps, char *, n + 1);
+	/* Make sure tal_array_length() works */
+	tal_resize(&deps, n + 1);
+	return deps;
 }
 
 static bool have_dep(char **deps, const char *dep)
@@ -199,7 +198,7 @@ get_all_deps(const void *ctx, const char *dir, const char *style,
 	unsigned int i;
 
 	deps = get_one(ctx, dir, style, get_info);
-	for (i = 0; i < talloc_array_length(deps)-1; i++) {
+	for (i = 0; i < tal_count(deps)-1; i++) {
 		char **newdeps;
 		unsigned int j;
 		char *subdir;
@@ -207,19 +206,18 @@ get_all_deps(const void *ctx, const char *dir, const char *style,
 		if (!strstarts(deps[i], "ccan/"))
 			continue;
 
-		subdir = talloc_asprintf(ctx, "%s/%s",
-					 find_ccan_dir(dir), deps[i]);
+		subdir = tal_fmt(ctx, "%s/%s", find_ccan_dir(dir), deps[i]);
 		newdeps = get_one(ctx, subdir, "depends", get_info);
 
 		/* Should be short, so brute-force out dups. */
-		for (j = 0; j < talloc_array_length(newdeps)-1; j++) {
+		for (j = 0; j < tal_count(newdeps)-1; j++) {
 			unsigned int num;
 
 			if (have_dep(deps, newdeps[j]))
 				continue;
 
-			num = talloc_array_length(deps)-1;
-			deps = talloc_realloc(NULL, deps, char *, num + 2);
+			num = tal_count(deps)-1;
+			tal_resize(&deps, num + 2);
 			deps[num] = newdeps[j];
 			deps[num+1] = NULL;
 		}
@@ -233,12 +231,11 @@ static char **get_one_libs(const void *ctx, const char *dir,
 {
 	char *cmd, **lines;
 
-	cmd = talloc_asprintf(ctx, "%s libs", get_info(ctx, dir));
+	cmd = tal_fmt(ctx, "%s libs", get_info(ctx, dir));
 	lines = lines_from_cmd(cmd, "%s", cmd);
 	/* Strip final NULL. */
 	if (lines)
-		lines = talloc_realloc(NULL, lines, char *,
-				       talloc_array_length(lines)-1);
+		tal_resize(&lines, tal_count(lines)-1);
 	return lines;
 }
 
@@ -247,13 +244,13 @@ static char **add_deps(char **deps1, char **deps2)
 {
 	unsigned int i, len;
 
-	len = talloc_array_length(deps1);
+	len = tal_count(deps1);
 
 	for (i = 0; deps2[i]; i++) {
 		if (have_dep(deps1, deps2[i]))
 			continue;
-		deps1 = talloc_realloc(NULL, deps1, char *, len + 1);
-		deps1[len-1] = talloc_steal(deps1, deps2[i]);
+		tal_resize(&deps1, len + 1);
+		deps1[len-1] = tal_strdup(deps1, deps2[i]);
 		deps1[len++] = NULL;
 	}
 	return deps1;
@@ -266,7 +263,7 @@ char **get_libs(const void *ctx, const char *dir, const char *style,
 	unsigned int i, len;
 
 	libs = get_one_libs(ctx, dir, get_info);
-	len = talloc_array_length(libs);
+	len = tal_count(libs);
 
 	if (style) {
 		deps = get_deps(ctx, dir, style, true, get_info);
@@ -282,12 +279,12 @@ char **get_libs(const void *ctx, const char *dir, const char *style,
 			if (!strstarts(deps[i], "ccan/"))
 				continue;
 
-			subdir = talloc_asprintf(ctx, "%s/%s",
-						 find_ccan_dir(dir), deps[i]);
+			subdir = tal_fmt(ctx, "%s/%s",
+					 find_ccan_dir(dir), deps[i]);
 
 			newlibs = get_one_libs(ctx, subdir, get_info);
-			newlen = talloc_array_length(newlibs);
-			libs = talloc_realloc(ctx, libs, char *, len + newlen);
+			newlen = tal_count(newlibs);
+			tal_resize(&libs, len + newlen);
 			memcpy(&libs[len], newlibs,
 			       sizeof(newlibs[0])*newlen);
 			len += newlen;
@@ -295,7 +292,7 @@ char **get_libs(const void *ctx, const char *dir, const char *style,
 	}
 
 	/* Append NULL entry. */
-	libs = talloc_realloc(ctx, libs, char *, len + 1);
+	tal_resize(&libs, len + 1);
 	libs[len] = NULL;
 	return libs;
 }
@@ -308,7 +305,7 @@ static char **uniquify_deps(char **deps)
 	if (!deps)
 		return NULL;
 
-	num = talloc_array_length(deps) - 1;
+	num = tal_count(deps) - 1;
 	for (i = 0; i < num; i++) {
 		for (j = i + 1; j < num; j++) {
 			if (streq(deps[i], deps[j])) {
@@ -319,8 +316,9 @@ static char **uniquify_deps(char **deps)
 		}
 	}
 	deps[num] = NULL;
-	/* Make sure talloc_array_length() works */
-	return talloc_realloc(NULL, deps, char *, num + 1);
+	/* Make sure tal_count() works */
+	tal_resize(&deps, num + 1);
+	return deps;
 }
 
 char **get_deps(const void *ctx, const char *dir, const char *style,

+ 22 - 23
tools/doc_extract-core.c

@@ -1,7 +1,6 @@
 /* This merely extracts, doesn't do XML or anything. */
-#include <ccan/talloc/talloc.h>
+#include <ccan/take/take.h>
 #include <ccan/str/str.h>
-#include <ccan/str_talloc/str_talloc.h>
 #include <err.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -22,24 +21,24 @@ static char **grab_doc(char **lines, unsigned int **linemap,
 	unsigned int i, num;
 	bool printing = false;
 
-	ret = talloc_array(NULL, char *, talloc_array_length(lines));
-	*linemap = talloc_array(ret, unsigned int, talloc_array_length(lines));
+	ret = tal_arr(NULL, char *, tal_count(lines));
+	*linemap = tal_arr(ret, unsigned int, tal_count(lines));
 
 	num = 0;
 	for (i = 0; lines[i]; i++) {
 		if (streq(lines[i], "/**")) {
 			printing = true;
 			if (num != 0) {
-				ret[num-1] = talloc_append_string(ret[num-1],
-								  "\n");
+				ret[num-1] = tal_strcat(NULL,
+							take(ret[num-1]), "\n");
 			}
 		} else if (streq(lines[i], " */")) 
 			printing = false;
 		else if (printing) {
 			if (strstarts(lines[i], " * "))
-				ret[num++] = talloc_strdup(ret, lines[i]+3);
+				ret[num++] = tal_strdup(ret, lines[i]+3);
 			else if (strstarts(lines[i], " *"))
-				ret[num++] = talloc_strdup(ret, lines[i]+2);
+				ret[num++] = tal_strdup(ret, lines[i]+2);
 			else {
 				/* Weird, malformed? */
 				static bool warned;
@@ -49,7 +48,7 @@ static char **grab_doc(char **lines, unsigned int **linemap,
 					      file, i+1);
 					warned++;
 				}
-				ret[num++] = talloc_strdup(ret, lines[i]);
+				ret[num++] = tal_strdup(ret, lines[i]);
 				if (strstr(lines[i], "*/"))
 					printing = false;
 			}
@@ -70,7 +69,7 @@ static char *is_section(const void *ctx, const char *line, char **value)
 	char *secname;
 
 	/* Any number of upper case words separated by spaces, ending in : */
-	if (!strreg(ctx, line,
+	if (!tal_strreg(ctx, line,
 		    "^([A-Z][a-zA-Z0-9_]*( [A-Z][a-zA-Z0-9_]*)*):[ \t\n]*(.*)",
 		    &secname, NULL, value))
 		return NULL;
@@ -117,17 +116,17 @@ static struct doc_section *new_section(struct list_head *list,
 	d = list_tail(list, struct doc_section, list);
 	if (d && empty_section(d)) {
 		list_del(&d->list);
-		talloc_free(d);
+		tal_free(d);
 	}
 
-	d = talloc(list, struct doc_section);
+	d = tal(list, struct doc_section);
 	d->function = function;
-	lowertype = talloc_size(d, strlen(type) + 1);
+	lowertype = tal_arr(d, char, strlen(type) + 1);
 	/* Canonicalize type to lower case. */
 	for (i = 0; i < strlen(type)+1; i++)
 		lowertype[i] = tolower(type[i]);
 	d->type = lowertype;
-	d->lines = NULL;
+	d->lines = tal_arr(d, char *, 0);
 	d->num_lines = 0;
 	d->srcline = srcline;
 
@@ -137,9 +136,9 @@ static struct doc_section *new_section(struct list_head *list,
 
 static void add_line(struct doc_section *curr, const char *line)
 {
-	curr->lines = talloc_realloc(curr, curr->lines, char *,
-				     curr->num_lines+1);
-	curr->lines[curr->num_lines++] = talloc_strdup(curr->lines, line);
+	char *myline = tal_strdup(curr->lines, line);
+	tal_expand(&curr->lines, &myline, 1);
+	curr->num_lines++;
 }
 
 /* We convert tabs to spaces here. */
@@ -149,8 +148,8 @@ static void add_detabbed_line(struct doc_section *curr, const char *rawline)
 	char *line;
 
 	/* Worst-case alloc: 8 spaces per tab. */
-	line = talloc_array(curr, char, strlen(rawline) +
-			    strcount(rawline, "\t") * 7 + 1);
+	line = tal_arr(curr, char, strlen(rawline) +
+		       strcount(rawline, "\t") * 7 + 1);
 	len = 0;
 
 	/* We keep track of the *effective* offset of i. */
@@ -170,7 +169,7 @@ static void add_detabbed_line(struct doc_section *curr, const char *rawline)
 	line[len] = '\0';
 
 	add_line(curr, line + off);
-	talloc_free(line);
+	tal_free(line);
 }
 
 /* Not very efficient: we could track prefix length while doing
@@ -216,7 +215,7 @@ struct list_head *extract_doc_sections(char **rawlines, const char *file)
 	unsigned int i;
 	struct list_head *list;
 
-	list = talloc(NULL, struct list_head);
+	list = tal(NULL, struct list_head);
 	list_head_init(list);
 
 	for (i = 0; lines[i]; i++) {
@@ -225,7 +224,7 @@ struct list_head *extract_doc_sections(char **rawlines, const char *file)
 
 		funclen = is_summary_line(lines[i]);
 		if (funclen) {
-			function = talloc_strndup(list, lines[i], funclen);
+			function = tal_strndup(list, lines[i], funclen);
 			curr = new_section(list, function, "summary",
 					   linemap[i]);
 			add_line(curr, lines[i] + funclen + 3);
@@ -246,6 +245,6 @@ struct list_head *extract_doc_sections(char **rawlines, const char *file)
 	list_for_each(list, curr, list)
 		trim_lines(curr);
 
-	talloc_free(lines);
+	tal_free(lines);
 	return list;
 }

+ 4 - 6
tools/doc_extract.c

@@ -1,7 +1,5 @@
 /* This merely extracts, doesn't do XML or anything. */
 #include <ccan/str/str.h>
-#include <ccan/str_talloc/str_talloc.h>
-#include <ccan/talloc/talloc.h>
 #include <ccan/err/err.h>
 #include "tools.h"
 #include <string.h>
@@ -47,15 +45,15 @@ int main(int argc, char *argv[])
 		struct list_head *list;
 		struct doc_section *d;
 
-		file = talloc_grab_file(NULL, argv[i], NULL);
+		file = tal_grab_file(NULL, argv[i], NULL);
 		if (!file)
 			err(1, "Reading file %s", argv[i]);
-		lines = strsplit(file, file, "\n");
+		lines = tal_strsplit(file, file, "\n", STR_EMPTY_OK);
 
 		list = extract_doc_sections(lines, argv[i]);
 		if (list_empty(list))
 			errx(1, "No documentation in file %s", argv[i]);
-		talloc_free(file);
+		tal_free(file);
 
 		if (streq(type, "functions")) {
 			const char *last = NULL;
@@ -84,7 +82,7 @@ int main(int argc, char *argv[])
 					printf("%s\n", d->lines[j]);
 			}
 		}
-		talloc_free(list);
+		tal_free(list);
 	}
 	return 0;
 }

+ 29 - 34
tools/manifest.c

@@ -1,10 +1,8 @@
 #include "config.h"
 #include "manifest.h"
 #include "tools.h"
-#include <ccan/talloc/talloc.h>
 #include <ccan/str/str.h>
-#include <ccan/str_talloc/str_talloc.h>
-#include <ccan/talloc_link/talloc_link.h>
+#include <ccan/tal/link/link.h>
 #include <ccan/hash/hash.h>
 #include <ccan/htable/htable_type.h>
 #include <ccan/noerr/noerr.h>
@@ -44,7 +42,7 @@ static struct htable_manifest *manifests;
 const char *get_ccan_file_contents(struct ccan_file *f)
 {
 	if (!f->contents) {
-		f->contents = talloc_grab_file(f, f->fullname,
+		f->contents = tal_grab_file(f, f->fullname,
 					       &f->contents_size);
 		if (!f->contents)
 			err(1, "Reading file %s", f->fullname);
@@ -55,10 +53,11 @@ const char *get_ccan_file_contents(struct ccan_file *f)
 char **get_ccan_file_lines(struct ccan_file *f)
 {
 	if (!f->lines)
-		f->lines = strsplit(f, get_ccan_file_contents(f), "\n");
+		f->lines = tal_strsplit(f, get_ccan_file_contents(f), "\n",
+					STR_EMPTY_OK);
 
 	/* FIXME: is f->num_lines necessary? */
-	f->num_lines = talloc_array_length(f->lines) - 1;
+	f->num_lines = tal_count(f->lines) - 1;
 	return f->lines;
 }
 
@@ -69,14 +68,14 @@ struct ccan_file *new_ccan_file(const void *ctx, const char *dir, char *name)
 
 	assert(dir[0] == '/');
 
-	f = talloc(ctx, struct ccan_file);
+	f = tal(ctx, struct ccan_file);
 	f->lines = NULL;
 	f->line_info = NULL;
 	f->doc_sections = NULL;
 	for (i = 0; i < ARRAY_SIZE(f->compiled); i++)
 		f->compiled[i] = NULL;
-	f->name = talloc_steal(f, name);
-	f->fullname = talloc_asprintf(f, "%s/%s", dir, f->name);
+	f->name = tal_steal(f, name);
+	f->fullname = tal_fmt(f, "%s/%s", dir, f->name);
 	f->contents = NULL;
 	f->simplified = NULL;
 	return f;
@@ -86,7 +85,7 @@ static void add_files(struct manifest *m, const char *dir)
 {
 	DIR *d;
 	struct dirent *ent;
-	char **subs = NULL;
+	char **subs = tal_arr(m, char *, 0);
 
 	if (dir[0])
 		d = opendir(dir);
@@ -105,19 +104,18 @@ static void add_files(struct manifest *m, const char *dir)
 			continue;
 
 		f = new_ccan_file(m, m->dir,
-				  talloc_asprintf(m, "%s%s",
-						  dir, ent->d_name));
+				  tal_fmt(m, "%s%s", dir, ent->d_name));
 		if (lstat(f->name, &st) != 0)
 			err(1, "lstat %s", f->name);
 
 		if (S_ISDIR(st.st_mode)) {
-			size_t len = talloc_array_length(subs);
-			subs = talloc_realloc(m, subs, char *, len+1);
-			subs[len] = talloc_append_string(f->name, "/");
+			size_t len = tal_count(subs);
+			tal_resize(&subs, len+1);
+			subs[len] = tal_strcat(subs, f->name, "/");
 			continue;
 		}
 		if (!S_ISREG(st.st_mode)) {
-			talloc_free(f);
+			tal_free(f);
 			continue;
 		}
 
@@ -164,10 +162,10 @@ static void add_files(struct manifest *m, const char *dir)
 		    && list_empty(&m->h_files))
 			errx(1, "No _info, C or H files found here!");
 
-		for (i = 0; i < talloc_array_length(subs); i++)
+		for (i = 0; i < tal_count(subs); i++)
 			add_files(m, subs[i]);
 	}
-	talloc_free(subs);
+	tal_free(subs);
 }
 
 static int cmp_names(struct ccan_file *const *a, struct ccan_file *const *b,
@@ -178,20 +176,18 @@ static int cmp_names(struct ccan_file *const *a, struct ccan_file *const *b,
 
 static void sort_files(struct list_head *list)
 {
-	struct ccan_file **files = NULL, *f;
-	unsigned int i, num;
+	struct ccan_file **files = tal_arr(NULL, struct ccan_file *, 0), *f;
+	unsigned int i;
 
-	num = 0;
 	while ((f = list_top(list, struct ccan_file, list)) != NULL) {
-		files = talloc_realloc(NULL, files, struct ccan_file *, num+1);
-		files[num++] = f;
+		tal_expand(&files, &f, 1);
 		list_del(&f->list);
 	}
-	asort(files, num, cmp_names, NULL);
+	asort(files, tal_count(files), cmp_names, NULL);
 
-	for (i = 0; i < num; i++)
+	for (i = 0; i < tal_count(files); i++)
 		list_add_tail(list, &files[i]->list);
-	talloc_free(files);
+	tal_free(files);
 }
 
 struct manifest *get_manifest(const void *ctx, const char *dir)
@@ -202,29 +198,28 @@ struct manifest *get_manifest(const void *ctx, const char *dir)
 	struct list_head *list;
 
 	if (!manifests) {
-		manifests = talloc(NULL, struct htable_manifest);
+		manifests = tal(NULL, struct htable_manifest);
 		htable_manifest_init(manifests);
 	}
 
-	olddir = talloc_getcwd(NULL);
+	olddir = tal_getcwd(NULL);
 	if (!olddir)
 		err(1, "Getting current directory");
 
 	if (chdir(dir) != 0)
 		err(1, "Failed to chdir to %s", dir);
 
-	canon_dir = talloc_getcwd(olddir);
+	canon_dir = tal_getcwd(olddir);
 	if (!canon_dir)
 		err(1, "Getting current directory");
 
 	m = htable_manifest_get(manifests, canon_dir);
 	if (m)
 		goto done;
-
-	m = talloc_linked(ctx, talloc(NULL, struct manifest));
+	m = tal_linkable(tal(NULL, struct manifest));
 	m->info_file = NULL;
 	m->compiled[COMPILE_NORMAL] = m->compiled[COMPILE_NOFEAT] = NULL;
-	m->dir = talloc_steal(m, canon_dir);
+	m->dir = tal_steal(m, canon_dir);
 	list_head_init(&m->c_files);
 	list_head_init(&m->h_files);
 	list_head_init(&m->api_tests);
@@ -259,12 +254,12 @@ struct manifest *get_manifest(const void *ctx, const char *dir)
 		    &m->compile_fail_tests)
 		sort_files(list);
 
-	htable_manifest_add(manifests, m);
+	htable_manifest_add(manifests, tal_link(manifests, m));
 
 done:
 	if (chdir(olddir) != 0)
 		err(1, "Returning to original directory '%s'", olddir);
-	talloc_free(olddir);
+	tal_free(olddir);
 
 	return m;
 }

+ 1 - 1
tools/manifest.h

@@ -83,7 +83,7 @@ struct ccan_file {
 	char *simplified;
 };
 
-/* A new ccan_file, with the given name (talloc_steal onto returned value). */
+/* A new ccan_file, with the given name (tal_steal onto returned value). */
 struct ccan_file *new_ccan_file(const void *ctx, const char *dir, char *name);
 
 /* Use this rather than accessing f->contents directly: loads on demand. */

+ 36 - 44
tools/namespacize.c

@@ -10,9 +10,8 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include "ccan/str/str.h"
-#include "ccan/str_talloc/str_talloc.h"
+#include "ccan/take/take.h"
 #include "ccan/rbuf/rbuf.h"
-#include "ccan/talloc/talloc.h"
 #include "ccan/err/err.h"
 #include "tools.h"
 
@@ -41,20 +40,18 @@ static char **get_dir(const char *dir)
 {
 	DIR *d;
 	struct dirent *ent;
-	char **names = NULL;
-	unsigned int size = 0;
+	char **names = tal_arr(NULL, char *, 0), *n;
 
 	d = opendir(dir);
 	if (!d)
 		return NULL;
 
 	while ((ent = readdir(d)) != NULL) {
-		names = talloc_realloc(dir, names, char *, size + 2);
-		names[size++]
-			= talloc_asprintf(names, "%s/%s", dir, ent->d_name);
+		n = tal_fmt(names, "%s/%s", dir, ent->d_name);
+		tal_expand(&names, &n, 1);
 	}
-	/* FIXME: if the loop doesn't run at least once, we'll segfault here */
-	names[size] = NULL;
+	n = NULL;
+	tal_expand(&names, &n, 1);
 	closedir(d);
 	return names;
 }
@@ -86,9 +83,9 @@ static void add_replace(struct replace **repl, const char *str)
 		if (streq(i->string, str))
 			return;
 
-	new = talloc(*repl, struct replace);
+	new = tal(*repl, struct replace);
 	new->next = *repl;
-	new->string = talloc_strdup(new, str);
+	new->string = tal_strdup(new, str);
 	*repl = new;
 }
 
@@ -97,9 +94,9 @@ static void add_replace_tok(struct replace **repl, const char *s)
 	struct replace *new;
 	unsigned int len = strspn(s, IDENT_CHARS);
 
-	new = talloc(*repl, struct replace);
+	new = tal(*repl, struct replace);
 	new->next = *repl;
-	new->string = talloc_strndup(new, s, len);
+	new->string = tal_strndup(new, s, len);
 	*repl = new;
 }
 
@@ -124,7 +121,7 @@ static void look_for_macros(char *contents, struct replace **repl)
 				len = strspn(p, IDENT_CHARS);
 				if (len) {
 					char *s;
-					s = talloc_strndup(contents, p, len);
+					s = tal_strndup(contents, p, len);
 					/* Don't wrap idempotent wrappers */
 					if (!strstarts(s, "CCAN_")) {
 						verbose("Found %s\n", s);
@@ -164,7 +161,7 @@ static char *get_statement(const void *ctx, char **p)
 {
 	unsigned brackets = 0;
 	bool seen_brackets = false;
-	char *answer = talloc_strdup(ctx, "");
+	char *answer = tal_strdup(ctx, "");
 
 	for (;;) {
 		if ((*p)[0] == '/' && (*p)[1] == '/')
@@ -190,10 +187,7 @@ static char *get_statement(const void *ctx, char **p)
 				brackets--;
 
 			if (answer[0] != '\0' || c != ' ') {
-				answer = talloc_realloc(NULL, answer, char,
-							strlen(answer) + 2);
-				answer[strlen(answer)+1] = '\0';
-				answer[strlen(answer)] = c;
+				tal_append_fmt(&answer, "%c", c);
 			}
 			if (c == '}' && seen_brackets && brackets == 0) {
 				(*p)++;
@@ -261,8 +255,8 @@ static void analyze_headers(const char *dir, struct replace **repl)
 	char *hdr, *contents;
 
 	/* Get hold of header, assume that's it. */
-	hdr = talloc_asprintf(dir, "%s/%s.h", dir, talloc_basename(dir, dir));
-	contents = talloc_grab_file(dir, hdr, NULL);
+	hdr = tal_fmt(dir, "%s/%s.h", dir, tal_basename(dir, dir));
+	contents = tal_grab_file(dir, hdr, NULL);
 	if (!contents)
 		err(1, "Reading %s", hdr);
 
@@ -279,7 +273,7 @@ static void analyze_headers(const char *dir, struct replace **repl)
 
 static void write_replacement_file(const char *dir, struct replace **repl)
 {
-	char *replname = talloc_asprintf(dir, "%s/.namespacize", dir);
+	char *replname = tal_fmt(dir, "%s/.namespacize", dir);
 	int fd;
 	struct replace *r;
 
@@ -305,10 +299,9 @@ static void write_replacement_file(const char *dir, struct replace **repl)
 	close(fd);
 }
 
-static int unlink_destroy(char *name)
+static void unlink_destroy(char *name)
 {
 	unlink(name);
-	return 0;
 }
 
 static char *find_word(char *f, const char *str)
@@ -338,7 +331,7 @@ static const char *rewrite_file(const char *filename,
 	int fd;
 
 	verbose("Rewriting %s\n", filename);
-	file = talloc_grab_file(filename, filename, NULL);
+	file = tal_grab_file(filename, filename, NULL);
 	if (!file)
 		err(1, "Reading file %s", filename);
 
@@ -347,7 +340,7 @@ static const char *rewrite_file(const char *filename,
 
 		while ((p = find_word(file, repl->string)) != NULL) {
 			unsigned int off;
-			char *new = talloc_array(file, char, strlen(file)+6);
+			char *new = tal_arr(file, char, strlen(file)+6);
 
 			off = p - file;
 			memcpy(new, file, off);
@@ -361,13 +354,12 @@ static const char *rewrite_file(const char *filename,
 	}
 
 	/* If we exit for some reason, we want this erased. */
-	newname = talloc_asprintf(talloc_autofree_context(), "%s.tmp",
-				  filename);
+	newname = tal_fmt(autofree(), "%s.tmp", filename);
 	fd = open(newname, O_WRONLY|O_CREAT|O_EXCL, 0644);
 	if (fd < 0)
 		err(1, "Creating %s", newname);
 
-	talloc_set_destructor(newname, unlink_destroy);
+	tal_add_destructor(newname, unlink_destroy);
 	if (write(fd, file, strlen(file)) != strlen(file)) {
 		if (errno == 0)
 			errx(1, "Short write to %s: disk full?", newname);
@@ -394,7 +386,7 @@ static void setup_adjust_files(const char *dir,
 		if (strends(*files, "/test"))
 			setup_adjust_files(*files, repl, adj);
 		else if (strends(*files, ".c") || strends(*files, ".h")) {
-			struct adjusted *a = talloc(dir, struct adjusted);
+			struct adjusted *a = tal(dir, struct adjusted);
 			a->next = *adj;
 			a->file = *files;
 			a->tmpfile = rewrite_file(a->file, repl);
@@ -421,7 +413,7 @@ static void convert_dir(const char *dir)
 	struct adjusted *adj = NULL;
 
 	/* Remove any ugly trailing slashes. */
-	name = talloc_strdup(NULL, dir);
+	name = tal_strdup(NULL, dir);
 	while (strends(name, "/"))
 		name[strlen(name)-1] = '\0';
 
@@ -429,31 +421,31 @@ static void convert_dir(const char *dir)
 	write_replacement_file(name, &replace);
 	setup_adjust_files(name, replace, &adj);
 	rename_files(adj);
-	talloc_free(name);
-	talloc_free(replace);
+	tal_free(name);
+	tal_free(replace);
 }
 
 static struct replace *read_replacement_file(const char *depdir)
 {
 	struct replace *repl = NULL;
-	char *replname = talloc_asprintf(depdir, "%s/.namespacize", depdir);
+	char *replname = tal_fmt(depdir, "%s/.namespacize", depdir);
 	char *file, **line;
 
-	file = talloc_grab_file(replname, replname, NULL);
+	file = tal_grab_file(replname, replname, NULL);
 	if (!file) {
 		if (errno != ENOENT)
 			err(1, "Opening %s", replname);
 		return NULL;
 	}
 
-	for (line = strsplit(file, file, "\n"); *line; line++)
+	for (line = tal_strsplit(file, file, "\n", STR_EMPTY_OK); *line; line++)
 		add_replace(&repl, *line);
 	return repl;
 }
 
 static void adjust_dir(const char *dir)
 {
-	char *parent = talloc_dirname(talloc_autofree_context(), dir);
+	char *parent = tal_dirname(autofree(), dir);
 	char **deps;
 
 	verbose("Adjusting %s\n", dir);
@@ -465,7 +457,7 @@ static void adjust_dir(const char *dir)
 		struct adjusted *adj = NULL;
 		struct replace *repl;
 
-		depdir = talloc_asprintf(parent, "%s/%s", parent, *deps);
+		depdir = tal_fmt(parent, "%s/%s", parent, *deps);
 		repl = read_replacement_file(depdir);
 		if (repl) {
 			verbose("%s has been namespacized\n", depdir);
@@ -473,16 +465,16 @@ static void adjust_dir(const char *dir)
 			rename_files(adj);
 		} else
 			verbose("%s has not been namespacized\n", depdir);
-		talloc_free(depdir);
+		tal_free(depdir);
 	}
 	verbose_unindent();
-	talloc_free(parent);
+	tal_free(parent);
 }
 
 static void adjust_dependents(const char *dir)
 {
-	char *parent = talloc_dirname(NULL, dir);
-	char *base = talloc_basename(parent, dir);
+	char *parent = tal_dirname(NULL, dir);
+	char *base = tal_basename(parent, dir);
 	char **file;
 
 	verbose("Looking for dependents in %s\n", parent);
@@ -491,10 +483,10 @@ static void adjust_dependents(const char *dir)
 		char *info, **deps;
 		bool isdep = false;
 
-		if (talloc_basename(*file, *file)[0] == '.')
+		if (tal_basename(*file, *file)[0] == '.')
 			continue;
 
-		info = talloc_asprintf(*file, "%s/_info", *file);
+		info = tal_fmt(*file, "%s/_info", *file);
 		if (access(info, R_OK) != 0)
 			continue;
 

+ 6 - 8
tools/read_config_header.c

@@ -1,7 +1,5 @@
 #include <ccan/err/err.h>
 #include <ccan/str/str.h>
-#include <ccan/str_talloc/str_talloc.h>
-#include <ccan/talloc/talloc.h>
 #include "read_config_header.h"
 #include "tools.h"
 #include <string.h>
@@ -16,7 +14,7 @@ char *get_symbol_token(void *ctx, const char **line)
 	toklen = strspn(*line, IDENT_CHARS);
 	if (!toklen)
 		return NULL;
-	ret = talloc_strndup(ctx, *line, toklen);
+	ret = tal_strndup(ctx, *line, toklen);
 	*line += toklen;
 	return ret;
 }
@@ -92,19 +90,19 @@ char *read_config_header(const char *ccan_dir,
 			 const char **compiler, const char **cflags,
 			 bool verbose)
 {
-	char *fname = talloc_asprintf(NULL, "%s/config.h", ccan_dir);
+	char *fname = tal_fmt(NULL, "%s/config.h", ccan_dir);
 	char **lines;
 	unsigned int i;
 	char *config_header;
 
-	config_header = talloc_grab_file(NULL, fname, NULL);
-	talloc_free(fname);
+	config_header = tal_grab_file(NULL, fname, NULL);
+	tal_free(fname);
 
 	if (!config_header)
 		goto out;
 
-	lines = strsplit(config_header, config_header, "\n");
-	for (i = 0; i < talloc_array_length(lines) - 1; i++) {
+	lines = tal_strsplit(config_header, config_header, "\n", STR_EMPTY_OK);
+	for (i = 0; i < tal_count(lines) - 1; i++) {
 		char *sym;
 		const char **line = (const char **)&lines[i];
 

+ 68 - 61
tools/tools.c

@@ -1,4 +1,4 @@
-#include <ccan/talloc/talloc.h>
+#include <ccan/take/take.h>
 #include <ccan/err/err.h>
 #include <ccan/noerr/noerr.h>
 #include <ccan/rbuf/rbuf.h>
@@ -25,38 +25,38 @@ bool tools_verbose = false;
 /* Ten minutes. */
 const unsigned int default_timeout_ms = 10 * 60 * 1000;
 
-char *talloc_basename(const void *ctx, const char *dir)
+char *tal_basename(const void *ctx, const char *dir)
 {
-	char *p = strrchr(dir, '/');
+	const char *p = strrchr(dir, '/');
 
 	if (!p)
-		return talloc_strdup(ctx, dir);
-	return talloc_strdup(ctx, p+1);
+		return tal_strdup(ctx, dir);
+	return tal_strdup(ctx, p+1);
 }
 
-char *talloc_dirname(const void *ctx, const char *dir)
+char *tal_dirname(const void *ctx, const char *dir)
 {
-	char *p = strrchr(dir, '/');
+	const char *p = strrchr(dir, '/');
 
 	if (!p)
-		return talloc_strdup(ctx, ".");
-	return talloc_strndup(ctx, dir, p - dir);
+		return tal_strdup(ctx, ".");
+	return tal_strndup(ctx, dir, p - dir);
 }
 
-char *talloc_getcwd(const void *ctx)
+char *tal_getcwd(const void *ctx)
 {
 	unsigned int len;
 	char *cwd;
 
 	/* *This* is why people hate C. */
 	len = 32;
-	cwd = talloc_array(ctx, char, len);
+	cwd = tal_arr(ctx, char, len);
 	while (!getcwd(cwd, len)) {
 		if (errno != ERANGE) {
-			talloc_free(cwd);
+			tal_free(cwd);
 			return NULL;
 		}
-		cwd = talloc_realloc(ctx, cwd, char, len *= 2);
+		tal_resize(&cwd, len *= 2);
 	}
 	return cwd;
 }
@@ -77,8 +77,8 @@ char *run_with_timeout(const void *ctx, const char *cmd,
 
 	*ok = false;
 	if (pipe(p) != 0)
-		return talloc_asprintf(ctx, "Failed to create pipe: %s",
-				       strerror(errno));
+		return tal_fmt(ctx, "Failed to create pipe: %s",
+			       strerror(errno));
 
 	if (tools_verbose)
 		printf("Running: %s\n", cmd);
@@ -90,8 +90,7 @@ char *run_with_timeout(const void *ctx, const char *cmd,
 	if (pid == -1) {
 		close_noerr(p[0]);
 		close_noerr(p[1]);
-		return talloc_asprintf(ctx, "Failed to fork: %s",
-				       strerror(errno));
+		return tal_fmt(ctx, "Failed to fork: %s", strerror(errno));
 	}
 
 	if (pid == 0) {
@@ -117,11 +116,9 @@ char *run_with_timeout(const void *ctx, const char *cmd,
 	}
 
 	close(p[1]);
-	rbuf_init(&in, p[0], talloc_array(ctx, char, 4096), 4096);
-	if (!rbuf_read_str(&in, 0, do_talloc_realloc) && errno) {
-		talloc_free(in.buf);
-		in.buf = NULL;
-	}
+	rbuf_init(&in, p[0], tal_arr(ctx, char, 4096), 4096);
+	if (!rbuf_read_str(&in, 0, do_tal_realloc) && errno)
+		in.buf = tal_free(in.buf);
 
 	/* This shouldn't fail... */
 	if (waitpid(pid, &status, 0) != pid)
@@ -144,7 +141,7 @@ char *run_with_timeout(const void *ctx, const char *cmd,
 	return in.buf;
 }
 
-/* Tallocs *output off ctx; return false if command fails. */
+/* Tals *output off ctx; return false if command fails. */
 bool run_command(const void *ctx, unsigned int *time_ms, char **output,
 		 const char *fmt, ...)
 {
@@ -156,12 +153,12 @@ bool run_command(const void *ctx, unsigned int *time_ms, char **output,
 	if (!time_ms)
 		time_ms = &default_time;
 	else if (*time_ms == 0) {
-		*output = talloc_strdup(ctx, "\n== TIMED OUT ==\n");
+		*output = tal_strdup(ctx, "\n== TIMED OUT ==\n");
 		return false;
 	}
 
 	va_start(ap, fmt);
-	cmd = talloc_vasprintf(ctx, fmt, ap);
+	cmd = tal_vfmt(ctx, fmt, ap);
 	va_end(ap);
 
 	*output = run_with_timeout(ctx, cmd, &ok, time_ms);
@@ -170,12 +167,11 @@ bool run_command(const void *ctx, unsigned int *time_ms, char **output,
 	if (!*output)
 		err(1, "Problem running child");
 	if (*time_ms == 0)
-		*output = talloc_asprintf_append(*output,
-						 "\n== TIMED OUT ==\n");
+		*output = tal_strcat(ctx, take(*output), "\n== TIMED OUT ==\n");
 	return false;
 }
 
-static int unlink_all(const char *dir)
+static void unlink_all(const char *dir)
 {
 	char cmd[strlen(dir) + sizeof("rm -rf ")];
 	sprintf(cmd, "rm -rf %s", dir);
@@ -183,66 +179,78 @@ static int unlink_all(const char *dir)
 		printf("Running: %s\n", cmd);
 	if (system(cmd) != 0)
 		warn("Could not remove temporary work in %s", dir);
-	return 0;
 }
 
-const char *temp_dir(const void *ctx)
+static pid_t *afree;
+static void free_autofree(void)
+{
+	if (*afree == getpid())
+		tal_free(afree);
+}
+
+tal_t *autofree(void)
+{
+	if (!afree) {
+		afree = tal(NULL, pid_t);
+		*afree = getpid();
+		atexit(free_autofree);
+	}
+	return afree;
+}
+
+const char *temp_dir(void)
 {
 	/* For first call, create dir. */
 	while (!tmpdir) {
 		tmpdir = getenv("TMPDIR");
 		if (!tmpdir)
 			tmpdir = "/tmp";
-		tmpdir = talloc_asprintf(talloc_autofree_context(),
-					 "%s/ccanlint-%u.%lu",
-					 tmpdir, getpid(), random());
+		tmpdir = tal_fmt(autofree(), "%s/ccanlint-%u.%lu",
+				 tmpdir, getpid(), random());
 		if (mkdir(tmpdir, 0700) != 0) {
 			if (errno == EEXIST) {
-				talloc_free(tmpdir);
+				tal_free(tmpdir);
 				tmpdir = NULL;
 				continue;
 			}
 			err(1, "mkdir %s failed", tmpdir);
 		}
-		talloc_set_destructor(tmpdir, unlink_all);
+		tal_add_destructor(tmpdir, unlink_all);
 		if (tools_verbose)
 			printf("Created temporary directory %s\n", tmpdir);
 	}
 	return tmpdir;
 }
 
-int unlink_file_destructor(char *filename)
+void keep_temp_dir(void)
 {
-	unlink(filename);
-	return 0;
+	tal_del_destructor(temp_dir(), unlink_all);
 }
 
 char *temp_file(const void *ctx, const char *extension, const char *srcname)
 {
 	unsigned baselen;
-	char *f, *suffix = talloc_strdup(ctx, "");
+	char *f, *suffix = tal_strdup(ctx, "");
 	struct stat st;
 	unsigned int count = 0;
 
-	srcname = talloc_basename(ctx, srcname);
+	srcname = tal_basename(ctx, srcname);
 	if (strrchr(srcname, '.'))
 		baselen = strrchr(srcname, '.') - srcname;
 	else
 		baselen = strlen(srcname);
 
 	do {
-		f = talloc_asprintf(ctx, "%s/%.*s%s%s",
-				    temp_dir(ctx),
-				    baselen, srcname,
-				    suffix, extension);
-		talloc_free(suffix);
-		suffix = talloc_asprintf(ctx, "-%u", ++count);
+		f = tal_fmt(ctx, "%s/%.*s%s%s",
+			    temp_dir(), baselen, srcname, suffix, extension);
+		tal_free(suffix);
+		suffix = tal_fmt(ctx, "-%u", ++count);
 	} while (lstat(f, &st) == 0);
 
 	if (tools_verbose)
 		printf("Creating file %s\n", f);
 
-	talloc_free(suffix);
+	tal_free(suffix);
 	return f;
 }
 
@@ -264,7 +272,7 @@ bool move_file(const char *oldname, const char *newname)
 	}
 
 	/* Try copy and delete: not atomic! */
-	contents = talloc_grab_file(NULL, oldname, &size);
+	contents = tal_grab_file(NULL, oldname, &size);
 	if (!contents) {
 		if (tools_verbose)
 			printf("read failed: %s\n", strerror(errno));
@@ -294,28 +302,27 @@ bool move_file(const char *oldname, const char *newname)
 	}
 
 free:
-	talloc_free(contents);
+	tal_free(contents);
 	return ret;
 }
 
-void *do_talloc_realloc(void *p, size_t size)
+void *do_tal_realloc(void *p, size_t size)
 {
-	return talloc_realloc(NULL, p, char, size);
+	tal_resize((char **)&p, size);
+	return p;
 }
 
-void *talloc_grab_file(const void *ctx, const char *filename, size_t *size)
+void *tal_grab_file(const void *ctx, const char *filename, size_t *size)
 {
 	struct rbuf rbuf;
-	char *buf = talloc_size(ctx, 4096);
+	char *buf = tal_arr(ctx, char, 0);
 
-	if (!rbuf_open(&rbuf, filename, buf, 4096)) {
-		talloc_free(buf);
-		return NULL;
-	}
-	if (!rbuf_fill_all(&rbuf, do_talloc_realloc)) {
-		talloc_free(rbuf.buf);
-		rbuf.buf = NULL;
-	} else {
+	if (!rbuf_open(&rbuf, filename, buf, 0))
+		return tal_free(buf);
+
+	if (!rbuf_fill_all(&rbuf, do_tal_realloc) && errno)
+		rbuf.buf = tal_free(rbuf.buf);
+	else {
 		rbuf.buf[rbuf.len] = '\0';
 		if (size)
 			*size = rbuf.len;

+ 12 - 9
tools/tools.h

@@ -3,6 +3,8 @@
 #include "config.h"
 #include <ccan/compiler/compiler.h>
 #include <ccan/rbuf/rbuf.h>
+#include <ccan/tal/tal.h>
+#include <ccan/tal/str/str.h>
 #include <stdlib.h>
 #include <stdbool.h>
 
@@ -44,20 +46,24 @@ char **get_libs(const void *ctx, const char *dir, const char *style,
 /* From tools.c */
 /* If set, print all commands run, all output they give and exit status. */
 extern bool tools_verbose;
-char *talloc_basename(const void *ctx, const char *dir);
-char *talloc_dirname(const void *ctx, const char *dir);
-char *talloc_getcwd(const void *ctx);
+char *tal_basename(const void *ctx, const char *dir);
+char *tal_dirname(const void *ctx, const char *dir);
+char *tal_getcwd(const void *ctx);
 bool PRINTF_FMT(4,5) run_command(const void *ctx,
 				 unsigned int *time_ms,
 				 char **output,
 				 const char *fmt, ...);
 char *run_with_timeout(const void *ctx, const char *cmd,
 		       bool *ok, unsigned *timeout_ms);
-const char *temp_dir(const void *ctx);
+const char *temp_dir(void);
+void keep_temp_dir(void);
 bool move_file(const char *oldname, const char *newname);
 
-void *do_talloc_realloc(void *p, size_t size);
-void *talloc_grab_file(const void *ctx, const char *filename, size_t *size);
+void *do_tal_realloc(void *p, size_t size);
+void *tal_grab_file(const void *ctx, const char *filename, size_t *size);
+
+/* Freed on exit: a good parent for auto cleanup. */
+tal_t *autofree(void);
 
 /* From compile.c.
  *
@@ -86,9 +92,6 @@ char *temp_file(const void *ctx, const char *extension, const char *srcname);
 /* Default wait for run_command.  Should never time out. */
 extern const unsigned int default_timeout_ms;
 
-/* Talloc destructor which unlinks file. */
-int unlink_file_destructor(char *filename);
-
 /* Get ccan/ top dir, given a directory within it. */
 const char *find_ccan_dir(const char *base);
 #endif /* CCAN_TOOLS_H */