#include #include #include "config.h" /** * tal - compact tree allocator routines (inspired by talloc) * * Tal is a hierarchical allocator; any pointer allocated by tal can * become the parent of another allocation. When you free that parent, * the children (and grandchildren, etc) are automatically freed. * * This allows you to build complex objects based on their lifetimes, eg: * * struct foo *X = tal(NULL, struct foo); * X->val = tal(X, int); * * and the pointer X->val would be a "child" of the tal context "X"; * tal_free(X->val) would free X->val as expected, by tal_free(X) would * free X and X->val. * * With an overhead of approximately 4 pointers per object * (vs. talloc's 12 pointers), it uses dynamic allocation for * destructors and child lists, so those operations can fail. It does * not support talloc's references or failing destructors. * * See Also: * ccan/tal/str (useful string helpers) * * Example: * #include * #include * #include * * // A structure containing a popened command. * struct command { * FILE *f; * char *command; * }; * * // When struct command is freed, we also want to pclose pipe. * static void close_cmd(struct command *cmd) * { * pclose(cmd->f); * } * * // This function opens a writable pipe to the given command. * static struct command *open_output_cmd(const tal_t *ctx, * const char *a0, const char *a1) * { * struct command *cmd = tal(ctx, struct command); * * if (!cmd) * return NULL; * * // Note that tal/str has helpers to make this much easier! * cmd->command = tal_arrz(cmd, char, strlen(a0) + strlen(a1) + 2); * if (!cmd->command) { * tal_free(cmd); * return NULL; * } * strcat(cmd->command, a0); * strcat(cmd->command, " "); * strcat(cmd->command, a1); * * cmd->f = popen(cmd->command, "w"); * if (!cmd->f) { * tal_free(cmd); * return NULL; * } * tal_add_destructor(cmd, close_cmd); * return cmd; * } * * int main(int argc, char *argv[]) * { * struct command *cmd; * * if (argc != 2) * errx(1, "Usage: %s \n", argv[0]); * * cmd = open_output_cmd(NULL, argv[1], "hello"); * if (!cmd) * err(1, "Running '%s hello'", argv[1]); * fprintf(cmd->f, "This is a test\n"); * tal_free(cmd); * return 0; * } * * License: BSD-MIT */ int main(int argc, char *argv[]) { if (argc != 2) return 1; if (strcmp(argv[1], "depends") == 0) { printf("ccan/compiler\n"); printf("ccan/likely\n"); printf("ccan/list\n"); printf("ccan/str\n"); printf("ccan/take\n"); printf("ccan/typesafe_cb\n"); return 0; } return 1; }