Files
damus/nostrdb/ccan/ccan/tal/_info
Rusty Russell a8d7d971b1 nostrdb: ccan: sync with normal versions.
This is the version of CCAN which CLN was using at the time these
were taken.  Unfortunately lots of whitespace has been changed,
but AFAICT no source changes.

Here's the command I ran (with ../ccan checked out to 1ae4c432):

```
make update-ccan CCAN_NEW="alignof array_size build_assert check_type container_of cppmagic likely list mem short_types str structeq take tal tal/str typesafe_cb utf8 endian crypto/sha256"
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: William Casarin <jb55@jb55.com>
2025-08-11 16:40:00 -07:00

109 lines
2.6 KiB
Plaintext

#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;
}