diff options
| author | William Casarin <jb55@jb55.com> | 2018-07-09 12:10:32 -0700 |
|---|---|---|
| committer | William Casarin <jb55@jb55.com> | 2018-07-09 12:10:32 -0700 |
| commit | 1b8fbbd843ddeb5fc81c9303db9c590a436d499b (patch) | |
| tree | a7227dfe8e4fbaee7b1e0b58b24994dce8078f3f /ccan/tal/_info | |
| parent | 37a9cdd2e80386f2c94e14e4f511284ae14c745a (diff) | |
progress
Diffstat (limited to 'ccan/tal/_info')
| -rw-r--r-- | ccan/tal/_info | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/ccan/tal/_info b/ccan/tal/_info new file mode 100644 index 0000000..5285c16 --- /dev/null +++ b/ccan/tal/_info @@ -0,0 +1,108 @@ +#include "config.h" +#include <stdio.h> +#include <string.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 <stdio.h> + * #include <err.h> + * #include <ccan/tal/tal.h> + * + * // 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 <command>\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/alignof\n"); + 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; +} |
