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>
This commit is contained in:
committed by
Daniel D’Aquino
parent
201cdd7edc
commit
a8d7d971b1
1
nostrdb/ccan/ccan/tal/LICENSE
Symbolic link
1
nostrdb/ccan/ccan/tal/LICENSE
Symbolic link
@@ -0,0 +1 @@
|
||||
../../licenses/BSD-MIT
|
||||
108
nostrdb/ccan/ccan/tal/_info
Normal file
108
nostrdb/ccan/ccan/tal/_info
Normal file
@@ -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;
|
||||
}
|
||||
26
nostrdb/ccan/ccan/tal/benchmark/Makefile
Normal file
26
nostrdb/ccan/ccan/tal/benchmark/Makefile
Normal file
@@ -0,0 +1,26 @@
|
||||
CFLAGS=-O3 -Wall -flto -I../../..
|
||||
#CFLAGS=-O3 -Wall -I../../..
|
||||
#CFLAGS=-g -Wall -I../../..
|
||||
LDFLAGS=-O3 -flto
|
||||
LDLIBS=-lrt
|
||||
|
||||
all: speed samba-allocs
|
||||
|
||||
speed: speed.o tal.o talloc.o time.o list.o take.o str.o
|
||||
samba-allocs: samba-allocs.o tal.o talloc.o time.o list.o take.o
|
||||
|
||||
tal.o: ../tal.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
str.o: ../str/str.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
talloc.o: ../../talloc/talloc.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
time.o: ../../time/time.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
list.o: ../../list/list.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
take.o: ../../take/take.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f speed samba-allocs *.o
|
||||
374
nostrdb/ccan/ccan/tal/benchmark/samba-allocs.c
Normal file
374
nostrdb/ccan/ccan/tal/benchmark/samba-allocs.c
Normal file
@@ -0,0 +1,374 @@
|
||||
/* Grab dump of Samba4 talloc tree to do benchmarks on it. */
|
||||
#include <ccan/talloc/talloc.h>
|
||||
#include <ccan/tal/tal.h>
|
||||
#include <ccan/time/time.h>
|
||||
#include <ccan/err/err.h>
|
||||
#include <ccan/str/str.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
struct node {
|
||||
void *n;
|
||||
struct node *parent;
|
||||
char *name;
|
||||
bool destructor;
|
||||
size_t len;
|
||||
unsigned int num_children;
|
||||
struct node *children[0];
|
||||
};
|
||||
|
||||
static int node_count;
|
||||
|
||||
static struct node *new_node(void)
|
||||
{
|
||||
node_count++;
|
||||
return calloc(sizeof(struct node), 1);
|
||||
}
|
||||
|
||||
/* struct db_context contains 282 bytes in 5 blocks (ref 0) d=(nil) 0x1f64e70 */
|
||||
static struct node *parse(const char *line)
|
||||
{
|
||||
struct node *n = new_node();
|
||||
const char *p;
|
||||
|
||||
p = strstr(line, " contains ");
|
||||
p += strlen(" contains ");
|
||||
p += strspn(line, " ");
|
||||
n->len = strtol(p, NULL, 0);
|
||||
p = strstr(p, "d=");
|
||||
if (p[2] != '(')
|
||||
n->destructor = true;
|
||||
return n;
|
||||
}
|
||||
|
||||
static void add_child(struct node *parent, struct node *child)
|
||||
{
|
||||
unsigned int i;
|
||||
struct node *oldp = parent;
|
||||
|
||||
parent = realloc(parent, sizeof(*parent)
|
||||
+ sizeof(parent->children[0]) * (parent->num_children+1));
|
||||
parent->children[parent->num_children++] = child;
|
||||
child->parent = parent;
|
||||
|
||||
if (parent == oldp)
|
||||
return;
|
||||
|
||||
/* Fix up children's parent pointers. */
|
||||
for (i = 0; i < parent->num_children-1; i++) {
|
||||
assert(parent->children[i]->parent == oldp);
|
||||
parent->children[i]->parent = parent;
|
||||
}
|
||||
|
||||
/* Fix up parent's child pointer. */
|
||||
if (parent->parent) {
|
||||
assert(parent->parent->children[parent->parent->num_children-1]
|
||||
== oldp);
|
||||
parent->parent->children[parent->parent->num_children-1]
|
||||
= parent;
|
||||
}
|
||||
}
|
||||
|
||||
/* Random string of required length */
|
||||
static char *namelen(int len)
|
||||
{
|
||||
char *p = malloc(len);
|
||||
memset(p, 'x', len-1);
|
||||
p[len-1] = '\0';
|
||||
return p;
|
||||
}
|
||||
|
||||
static struct node *read_nodes(FILE *f)
|
||||
{
|
||||
char line[4096];
|
||||
unsigned int curr_indent = 0, indent;
|
||||
struct node *n, *curr = new_node();
|
||||
|
||||
/* Ignore first line */
|
||||
fgets(line, 4096, f);
|
||||
|
||||
while (fgets(line, 4096, f)) {
|
||||
bool is_name;
|
||||
|
||||
indent = strspn(line, " ");
|
||||
|
||||
/* Ignore references for now. */
|
||||
if (strstarts(line + indent, "reference to: "))
|
||||
continue;
|
||||
|
||||
/* Blank name? Use offset of 'contains' to guess indent! */
|
||||
if (strstarts(line + indent, "contains "))
|
||||
indent -= 31;
|
||||
|
||||
is_name = strstarts(line + indent, ".name ");
|
||||
|
||||
n = parse(line + indent);
|
||||
if (is_name) {
|
||||
curr->name = namelen(n->len);
|
||||
free(n);
|
||||
} else {
|
||||
if (indent > curr_indent) {
|
||||
assert(indent == curr_indent + 4);
|
||||
curr_indent += 4;
|
||||
} else {
|
||||
/* Go back up to parent. */
|
||||
for (curr_indent += 4;
|
||||
curr_indent != indent;
|
||||
curr_indent -= 4)
|
||||
curr = curr->parent;
|
||||
}
|
||||
add_child(curr, n);
|
||||
curr = n;
|
||||
}
|
||||
}
|
||||
while (curr->parent) {
|
||||
curr = curr->parent;
|
||||
curr_indent -= 4;
|
||||
}
|
||||
assert(curr_indent == 0);
|
||||
return curr;
|
||||
}
|
||||
|
||||
static int unused_talloc_destructor(void *p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void do_tallocs(struct node *node)
|
||||
{
|
||||
unsigned int i;
|
||||
static int count;
|
||||
|
||||
if (count++ % 16 == 0)
|
||||
node->n = talloc_array(node->parent ? node->parent->n : NULL,
|
||||
char, node->len);
|
||||
else
|
||||
node->n = talloc_size(node->parent ? node->parent->n : NULL,
|
||||
node->len);
|
||||
if (node->destructor)
|
||||
talloc_set_destructor(node->n, unused_talloc_destructor);
|
||||
if (node->name)
|
||||
talloc_set_name(node->n, "%s", node->name);
|
||||
|
||||
for (i = 0; i < node->num_children; i++)
|
||||
do_tallocs(node->children[i]);
|
||||
}
|
||||
|
||||
static void free_tallocs(struct node *node)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < node->num_children; i++)
|
||||
free_tallocs(node->children[i]);
|
||||
|
||||
talloc_free(node->n);
|
||||
}
|
||||
|
||||
static void unused_tal_destructor(void *p)
|
||||
{
|
||||
}
|
||||
|
||||
static void do_tals(struct node *node)
|
||||
{
|
||||
unsigned int i;
|
||||
static int count;
|
||||
|
||||
node->n = tal_arr(node->parent ? node->parent->n : NULL,
|
||||
char, node->len);
|
||||
|
||||
if (node->destructor)
|
||||
tal_add_destructor(node->n, unused_tal_destructor);
|
||||
if (node->name)
|
||||
tal_set_name(node->n, node->name);
|
||||
|
||||
for (i = 0; i < node->num_children; i++)
|
||||
do_tals(node->children[i]);
|
||||
}
|
||||
|
||||
static void free_tals(struct node *node)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < node->num_children; i++)
|
||||
free_tals(node->children[i]);
|
||||
|
||||
tal_free(node->n);
|
||||
}
|
||||
|
||||
static void do_mallocs(struct node *node)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
node->n = malloc(node->len + (node->name ? strlen(node->name) + 1 : 1));
|
||||
|
||||
for (i = 0; i < node->num_children; i++)
|
||||
do_mallocs(node->children[i]);
|
||||
}
|
||||
|
||||
static void free_mallocs(struct node *node)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < node->num_children; i++)
|
||||
free_mallocs(node->children[i]);
|
||||
|
||||
free(node->n);
|
||||
}
|
||||
|
||||
/* See proc(5): field 23 is vsize, 24 is rss (in pages) */
|
||||
static void dump_vsize(void)
|
||||
{
|
||||
int fd, i;
|
||||
char buf[1000], *p = buf;
|
||||
|
||||
sprintf(buf, "/proc/%u/stat", getpid());
|
||||
fd = open(buf, O_RDONLY);
|
||||
read(fd, buf, sizeof(buf));
|
||||
close(fd);
|
||||
|
||||
for (i = 0; i < 22; i++) {
|
||||
p += strcspn(p, " ");
|
||||
p += strspn(p, " ");
|
||||
}
|
||||
i = atoi(p);
|
||||
printf("Virtual size = %i, ", i);
|
||||
p += strcspn(p, " ");
|
||||
p += strspn(p, " ");
|
||||
i = atoi(p);
|
||||
printf("RSS = %i\n", i * getpagesize());
|
||||
}
|
||||
|
||||
#define LOOPS 1000
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct timeabs start;
|
||||
struct timerel alloc_time, free_time;
|
||||
struct node *root;
|
||||
unsigned int i;
|
||||
FILE *f;
|
||||
bool run_talloc = true, run_tal = true, run_malloc = true;
|
||||
|
||||
f = argv[1] ? fopen(argv[1], "r") : stdin;
|
||||
root = read_nodes(f);
|
||||
fclose(f);
|
||||
printf("Read %u nodes\n", node_count);
|
||||
|
||||
if (argc > 2) {
|
||||
if (streq(argv[2], "--talloc-size")) {
|
||||
do_tallocs(root);
|
||||
dump_vsize();
|
||||
exit(0);
|
||||
}
|
||||
if (streq(argv[2], "--tal-size")) {
|
||||
do_tals(root);
|
||||
dump_vsize();
|
||||
exit(0);
|
||||
}
|
||||
if (strcmp(argv[2], "--talloc") == 0)
|
||||
run_tal = run_malloc = false;
|
||||
else if (strcmp(argv[2], "--tal") == 0)
|
||||
run_talloc = run_malloc = false;
|
||||
else if (strcmp(argv[2], "--malloc") == 0)
|
||||
run_talloc = run_tal = false;
|
||||
else
|
||||
errx(1, "Bad flag %s", argv[2]);
|
||||
}
|
||||
|
||||
if (!run_malloc)
|
||||
goto after_malloc;
|
||||
|
||||
alloc_time.ts.tv_sec = alloc_time.ts.tv_nsec = 0;
|
||||
free_time.ts.tv_sec = free_time.ts.tv_nsec = 0;
|
||||
for (i = 0; i < LOOPS; i++) {
|
||||
start = time_now();
|
||||
do_mallocs(root);
|
||||
alloc_time = timerel_add(alloc_time,
|
||||
time_between(time_now(), start));
|
||||
|
||||
start = time_now();
|
||||
free_mallocs(root);
|
||||
free_time = timerel_add(free_time,
|
||||
time_between(time_now(), start));
|
||||
}
|
||||
alloc_time = time_divide(alloc_time, i);
|
||||
free_time = time_divide(free_time, i);
|
||||
printf("Malloc time: %"PRIu64"ns\n", time_to_nsec(alloc_time));
|
||||
printf("Free time: %"PRIu64"ns\n", time_to_nsec(free_time));
|
||||
|
||||
after_malloc:
|
||||
if (!run_talloc)
|
||||
goto after_talloc;
|
||||
|
||||
alloc_time.ts.tv_sec = alloc_time.ts.tv_nsec = 0;
|
||||
free_time.ts.tv_sec = free_time.ts.tv_nsec = 0;
|
||||
for (i = 0; i < LOOPS; i++) {
|
||||
start = time_now();
|
||||
do_tallocs(root);
|
||||
alloc_time = timerel_add(alloc_time,
|
||||
time_between(time_now(), start));
|
||||
|
||||
start = time_now();
|
||||
free_tallocs(root);
|
||||
free_time = timerel_add(free_time,
|
||||
time_between(time_now(), start));
|
||||
}
|
||||
alloc_time = time_divide(alloc_time, i);
|
||||
free_time = time_divide(free_time, i);
|
||||
printf("Talloc time: %"PRIu64"ns\n", time_to_nsec(alloc_time));
|
||||
printf("talloc_free time: %"PRIu64"ns\n", time_to_nsec(free_time));
|
||||
|
||||
free_time.ts.tv_sec = free_time.ts.tv_nsec = 0;
|
||||
for (i = 0; i < LOOPS; i++) {
|
||||
do_tallocs(root);
|
||||
|
||||
start = time_now();
|
||||
talloc_free(root->n);
|
||||
free_time = timerel_add(free_time,
|
||||
time_between(time_now(), start));
|
||||
}
|
||||
free_time = time_divide(free_time, i);
|
||||
printf("Single talloc_free time: %"PRIu64"\n", time_to_nsec(free_time));
|
||||
|
||||
after_talloc:
|
||||
if (!run_tal)
|
||||
goto after_tal;
|
||||
|
||||
alloc_time.ts.tv_sec = alloc_time.ts.tv_nsec = 0;
|
||||
free_time.ts.tv_sec = free_time.ts.tv_nsec = 0;
|
||||
for (i = 0; i < LOOPS; i++) {
|
||||
start = time_now();
|
||||
do_tals(root);
|
||||
alloc_time = timerel_add(alloc_time,
|
||||
time_between(time_now(), start));
|
||||
|
||||
start = time_now();
|
||||
free_tals(root);
|
||||
free_time = timerel_add(free_time,
|
||||
time_between(time_now(), start));
|
||||
}
|
||||
alloc_time = time_divide(alloc_time, i);
|
||||
free_time = time_divide(free_time, i);
|
||||
printf("Tal time: %"PRIu64"ns\n", time_to_nsec(alloc_time));
|
||||
printf("Tal_free time: %"PRIu64"ns\n", time_to_nsec(free_time));
|
||||
|
||||
free_time.ts.tv_sec = free_time.ts.tv_nsec = 0;
|
||||
for (i = 0; i < LOOPS; i++) {
|
||||
do_tals(root);
|
||||
|
||||
start = time_now();
|
||||
tal_free(root->n);
|
||||
free_time = timerel_add(free_time,
|
||||
time_between(time_now(), start));
|
||||
}
|
||||
free_time = time_divide(free_time, i);
|
||||
printf("Single tal_free time: %"PRIu64"ns\n", time_to_nsec(free_time));
|
||||
after_tal:
|
||||
|
||||
return 0;
|
||||
}
|
||||
125
nostrdb/ccan/ccan/tal/benchmark/speed.c
Normal file
125
nostrdb/ccan/ccan/tal/benchmark/speed.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
Taken from samba/lib/talloc/testsuite.c: Unix SMB/CIFS implementation.
|
||||
|
||||
local testing of talloc routines.
|
||||
|
||||
Copyright (C) Andrew Tridgell 2004
|
||||
|
||||
** NOTE! The following LGPL license applies to the talloc
|
||||
** library. This does NOT imply that all of Samba is released
|
||||
** under the LGPL
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <ccan/talloc/talloc.h>
|
||||
#include <ccan/tal/tal.h>
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <ccan/time/time.h>
|
||||
#include <ccan/err/err.h>
|
||||
#include <string.h>
|
||||
|
||||
#define LOOPS 1024
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
void *ctx;
|
||||
unsigned count;
|
||||
int i, j;
|
||||
struct timeabs tv;
|
||||
void *p1, *p2[100], *p3[100];
|
||||
bool run_talloc = true, run_tal = true, run_malloc = true;
|
||||
|
||||
if (argv[1]) {
|
||||
if (strcmp(argv[1], "--talloc") == 0)
|
||||
run_tal = run_malloc = false;
|
||||
else if (strcmp(argv[1], "--tal") == 0)
|
||||
run_talloc = run_malloc = false;
|
||||
else if (strcmp(argv[1], "--malloc") == 0)
|
||||
run_talloc = run_tal = false;
|
||||
else
|
||||
errx(1, "Bad flag %s", argv[1]);
|
||||
}
|
||||
|
||||
if (!run_talloc)
|
||||
goto after_talloc;
|
||||
|
||||
ctx = talloc_new(NULL);
|
||||
tv = time_now();
|
||||
count = 0;
|
||||
do {
|
||||
for (i=0;i<LOOPS;i++) {
|
||||
p1 = talloc_size(ctx, LOOPS % 128);
|
||||
for (j = 0; j < 100; j++) {
|
||||
p2[j] = talloc_strdup(p1, "foo bar");
|
||||
p3[j] = talloc_size(p1, 300);
|
||||
}
|
||||
talloc_free(p1);
|
||||
}
|
||||
count += (1 + 200) * LOOPS;
|
||||
} while (time_between(time_now(), tv).ts.tv_sec < 5);
|
||||
|
||||
fprintf(stderr, "talloc: %.0f ops/sec\n", count/5.0);
|
||||
|
||||
talloc_free(ctx);
|
||||
|
||||
after_talloc:
|
||||
if (!run_tal)
|
||||
goto after_tal;
|
||||
|
||||
ctx = tal(NULL, char);
|
||||
tv = time_now();
|
||||
count = 0;
|
||||
do {
|
||||
for (i=0;i<LOOPS;i++) {
|
||||
p1 = tal_arr(ctx, char, LOOPS % 128);
|
||||
for (j = 0; j < 100; j++) {
|
||||
p2[j] = tal_strdup(p1, "foo bar");
|
||||
p3[j] = tal_arr(p1, char, 300);
|
||||
}
|
||||
tal_free(p1);
|
||||
}
|
||||
count += (1 + 200) * LOOPS;
|
||||
} while (time_between(time_now(), tv).ts.tv_sec < 5);
|
||||
fprintf(stderr, "tal: %.0f ops/sec\n", count/5.0);
|
||||
|
||||
tal_free(ctx);
|
||||
|
||||
after_tal:
|
||||
if (!run_malloc)
|
||||
goto after_malloc;
|
||||
|
||||
tv = time_now();
|
||||
count = 0;
|
||||
do {
|
||||
for (i=0;i<LOOPS;i++) {
|
||||
p1 = malloc(LOOPS % 128);
|
||||
for (j = 0; j < 100; j++) {
|
||||
p2[j] = strdup("foo bar");
|
||||
p3[j] = malloc(300);
|
||||
}
|
||||
for (j = 0; j < 100; j++) {
|
||||
free(p2[j]);
|
||||
free(p3[j]);
|
||||
}
|
||||
free(p1);
|
||||
}
|
||||
count += (1 + 200) * LOOPS;
|
||||
} while (time_between(time_now(), tv).ts.tv_sec < 5);
|
||||
fprintf(stderr, "malloc: %.0f ops/sec\n", count/5.0);
|
||||
|
||||
after_malloc:
|
||||
printf("success: speed\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
26137
nostrdb/ccan/ccan/tal/benchmark/talloc.dump
Normal file
26137
nostrdb/ccan/ccan/tal/benchmark/talloc.dump
Normal file
File diff suppressed because it is too large
Load Diff
1
nostrdb/ccan/ccan/tal/str/LICENSE
Symbolic link
1
nostrdb/ccan/ccan/tal/str/LICENSE
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../licenses/BSD-MIT
|
||||
61
nostrdb/ccan/ccan/tal/str/_info
Normal file
61
nostrdb/ccan/ccan/tal/str/_info
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* tal/str - string helper routines which use tal
|
||||
*
|
||||
* This is a grab bag of functions for string operations, designed to enhance
|
||||
* the standard string.h; these are separated from the non-tal-needing
|
||||
* string utilities in "str.h". Each string created by this library
|
||||
* will have tal_count() equal to strlen() + 1 (assuming you didn't create
|
||||
* a string containing a NUL, such as using tal_fmt("%c", 0)).
|
||||
*
|
||||
* Example:
|
||||
* #include <ccan/tal/str/str.h>
|
||||
* #include <ccan/tal/grab_file/grab_file.h>
|
||||
* #include <err.h>
|
||||
*
|
||||
* // Dumb demo program to double-linespace a file.
|
||||
* int main(int argc, char *argv[])
|
||||
* {
|
||||
* char *textfile;
|
||||
* char **lines;
|
||||
*
|
||||
* if (argc > 2)
|
||||
* errx(1, "Takes 0 or 1 arguments");
|
||||
* // Grab lines in file.
|
||||
* textfile = grab_file(NULL, argv[1]);
|
||||
* if (!textfile)
|
||||
* err(1, "Failed reading %s", argv[1]);
|
||||
* lines = tal_strsplit(textfile, textfile, "\n", STR_EMPTY_OK);
|
||||
*
|
||||
* // Join them back together with two linefeeds.
|
||||
* printf("%s", tal_strjoin(textfile, lines, "\n\n", STR_TRAIL));
|
||||
*
|
||||
* // Free everything, just because we can.
|
||||
* tal_free(textfile);
|
||||
* return 0;
|
||||
* }
|
||||
*
|
||||
* License: BSD-MIT
|
||||
* Author: Rusty Russell <rusty@rustcorp.com.au>
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc != 2)
|
||||
return 1;
|
||||
|
||||
if (strcmp(argv[1], "depends") == 0) {
|
||||
printf("ccan/str\n");
|
||||
#ifdef TAL_USE_TALLOC
|
||||
printf("ccan/tal/talloc\n");
|
||||
#else
|
||||
printf("ccan/tal\n");
|
||||
#endif
|
||||
printf("ccan/take\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -4,311 +4,312 @@
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include "str.h"
|
||||
#include <sys/types.h>
|
||||
#include <regex.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include "str.h"
|
||||
#include <ccan/str/str.h>
|
||||
|
||||
char *tal_strdup_(const tal_t *ctx, const char *p, const char *label)
|
||||
{
|
||||
/* We have to let through NULL for take(). */
|
||||
return tal_dup_arr_label(ctx, char, p, p ? strlen(p) + 1: 1, 0, label);
|
||||
/* We have to let through NULL for take(). */
|
||||
return tal_dup_arr_label(ctx, char, p, p ? strlen(p) + 1: 1, 0, label);
|
||||
}
|
||||
|
||||
char *tal_strndup_(const tal_t *ctx, const char *p, size_t n, const char *label)
|
||||
{
|
||||
size_t len;
|
||||
char *ret;
|
||||
size_t len;
|
||||
char *ret;
|
||||
|
||||
/* We have to let through NULL for take(). */
|
||||
if (likely(p))
|
||||
len = strnlen(p, n);
|
||||
else
|
||||
len = n;
|
||||
/* We have to let through NULL for take(). */
|
||||
if (likely(p))
|
||||
len = strnlen(p, n);
|
||||
else
|
||||
len = n;
|
||||
|
||||
ret = tal_dup_arr_label(ctx, char, p, len, 1, label);
|
||||
if (ret)
|
||||
ret[len] = '\0';
|
||||
return ret;
|
||||
ret = tal_dup_arr_label(ctx, char, p, len, 1, label);
|
||||
if (ret)
|
||||
ret[len] = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *tal_fmt_(const tal_t *ctx, const char *label, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *ret;
|
||||
va_list ap;
|
||||
char *ret;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = tal_vfmt_(ctx, fmt, ap, label);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
ret = tal_vfmt_(ctx, fmt, ap, label);
|
||||
va_end(ap);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool do_vfmt(char **buf, size_t off, const char *fmt, va_list ap)
|
||||
{
|
||||
/* A decent guess to start. */
|
||||
size_t max = strlen(fmt) * 2 + 1;
|
||||
bool ok;
|
||||
/* A decent guess to start. */
|
||||
size_t max = strlen(fmt) * 2 + 1;
|
||||
bool ok;
|
||||
|
||||
for (;;) {
|
||||
va_list ap2;
|
||||
int ret;
|
||||
for (;;) {
|
||||
va_list ap2;
|
||||
int ret;
|
||||
|
||||
if (!tal_resize(buf, off + max)) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
if (!tal_resize(buf, off + max)) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
|
||||
va_copy(ap2, ap);
|
||||
ret = vsnprintf(*buf + off, max, fmt, ap2);
|
||||
va_end(ap2);
|
||||
va_copy(ap2, ap);
|
||||
ret = vsnprintf(*buf + off, max, fmt, ap2);
|
||||
va_end(ap2);
|
||||
|
||||
if (ret < max) {
|
||||
ok = true;
|
||||
/* Make sure tal_count() is correct! */
|
||||
tal_resize(buf, off + ret + 1);
|
||||
break;
|
||||
}
|
||||
max *= 2;
|
||||
}
|
||||
if (ret < max) {
|
||||
ok = true;
|
||||
/* Make sure tal_count() is correct! */
|
||||
tal_resize(buf, off + ret + 1);
|
||||
break;
|
||||
}
|
||||
max *= 2;
|
||||
}
|
||||
|
||||
if (taken(fmt))
|
||||
tal_free(fmt);
|
||||
return ok;
|
||||
if (taken(fmt))
|
||||
tal_free(fmt);
|
||||
return ok;
|
||||
}
|
||||
|
||||
char *tal_vfmt_(const tal_t *ctx, const char *fmt, va_list ap, const char *label)
|
||||
{
|
||||
char *buf;
|
||||
char *buf;
|
||||
|
||||
if (!fmt && taken(fmt))
|
||||
return NULL;
|
||||
if (!fmt && taken(fmt))
|
||||
return NULL;
|
||||
|
||||
/* A decent guess to start. */
|
||||
buf = tal_arr_label(ctx, char, strlen(fmt) * 2, label);
|
||||
if (!do_vfmt(&buf, 0, fmt, ap))
|
||||
buf = tal_free(buf);
|
||||
return buf;
|
||||
/* A decent guess to start. */
|
||||
buf = tal_arr_label(ctx, char, strlen(fmt) * 2, label);
|
||||
if (!do_vfmt(&buf, 0, fmt, ap))
|
||||
buf = tal_free(buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
bool tal_append_vfmt(char **baseptr, const char *fmt, va_list ap)
|
||||
{
|
||||
if (!fmt && taken(fmt))
|
||||
return false;
|
||||
if (!fmt && taken(fmt))
|
||||
return false;
|
||||
|
||||
return do_vfmt(baseptr, strlen(*baseptr), fmt, ap);
|
||||
return do_vfmt(baseptr, strlen(*baseptr), fmt, ap);
|
||||
}
|
||||
|
||||
bool tal_append_fmt(char **baseptr, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
bool ret;
|
||||
va_list ap;
|
||||
bool ret;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = tal_append_vfmt(baseptr, fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
ret = tal_append_vfmt(baseptr, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *tal_strcat_(const tal_t *ctx, const char *s1, const char *s2,
|
||||
const char *label)
|
||||
const char *label)
|
||||
{
|
||||
size_t len1, len2;
|
||||
char *ret;
|
||||
size_t len1, len2;
|
||||
char *ret;
|
||||
|
||||
if (unlikely(!s2) && taken(s2)) {
|
||||
if (taken(s1))
|
||||
tal_free(s1);
|
||||
return NULL;
|
||||
}
|
||||
/* We have to let through NULL for take(). */
|
||||
len1 = s1 ? strlen(s1) : 0;
|
||||
len2 = strlen(s2);
|
||||
if (unlikely(!s2) && taken(s2)) {
|
||||
if (taken(s1))
|
||||
tal_free(s1);
|
||||
return NULL;
|
||||
}
|
||||
/* We have to let through NULL for take(). */
|
||||
len1 = s1 ? strlen(s1) : 0;
|
||||
len2 = strlen(s2);
|
||||
|
||||
ret = tal_dup_arr_label(ctx, char, s1, len1, len2 + 1, label);
|
||||
if (likely(ret))
|
||||
memcpy(ret + len1, s2, len2 + 1);
|
||||
ret = tal_dup_arr_label(ctx, char, s1, len1, len2 + 1, label);
|
||||
if (likely(ret))
|
||||
memcpy(ret + len1, s2, len2 + 1);
|
||||
|
||||
if (taken(s2))
|
||||
tal_free(s2);
|
||||
return ret;
|
||||
if (taken(s2))
|
||||
tal_free(s2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char **tal_strsplit_(const tal_t *ctx,
|
||||
const char *string, const char *delims, enum strsplit flags,
|
||||
const char *label)
|
||||
const char *string, const char *delims, enum strsplit flags,
|
||||
const char *label)
|
||||
{
|
||||
char **parts, *str;
|
||||
size_t max = 64, num = 0;
|
||||
char **parts, *str;
|
||||
size_t max = 64, num = 0;
|
||||
|
||||
parts = tal_arr(ctx, char *, max + 1);
|
||||
if (unlikely(!parts)) {
|
||||
if (taken(string))
|
||||
tal_free(string);
|
||||
if (taken(delims))
|
||||
tal_free(delims);
|
||||
return NULL;
|
||||
}
|
||||
str = tal_strdup(parts, string);
|
||||
if (unlikely(!str))
|
||||
goto fail;
|
||||
if (unlikely(!delims) && is_taken(delims))
|
||||
goto fail;
|
||||
parts = tal_arr(ctx, char *, max + 1);
|
||||
if (unlikely(!parts)) {
|
||||
if (taken(string))
|
||||
tal_free(string);
|
||||
if (taken(delims))
|
||||
tal_free(delims);
|
||||
return NULL;
|
||||
}
|
||||
str = tal_strdup(parts, string);
|
||||
if (unlikely(!str))
|
||||
goto fail;
|
||||
if (unlikely(!delims) && is_taken(delims))
|
||||
goto fail;
|
||||
|
||||
if (flags == STR_NO_EMPTY)
|
||||
str += strspn(str, delims);
|
||||
if (flags == STR_NO_EMPTY)
|
||||
str += strspn(str, delims);
|
||||
|
||||
while (*str != '\0') {
|
||||
size_t len = strcspn(str, delims), dlen;
|
||||
while (*str != '\0') {
|
||||
size_t len = strcspn(str, delims), dlen;
|
||||
|
||||
parts[num] = str;
|
||||
dlen = strspn(str + len, delims);
|
||||
parts[num][len] = '\0';
|
||||
if (flags == STR_EMPTY_OK && dlen)
|
||||
dlen = 1;
|
||||
str += len + dlen;
|
||||
if (++num == max && !tal_resize(&parts, max*=2 + 1))
|
||||
goto fail;
|
||||
}
|
||||
parts[num] = NULL;
|
||||
parts[num] = str;
|
||||
dlen = strspn(str + len, delims);
|
||||
parts[num][len] = '\0';
|
||||
if (flags == STR_EMPTY_OK && dlen)
|
||||
dlen = 1;
|
||||
str += len + dlen;
|
||||
if (++num == max && !tal_resize(&parts, max*=2 + 1))
|
||||
goto fail;
|
||||
}
|
||||
parts[num] = NULL;
|
||||
|
||||
/* Ensure that tal_count() is correct. */
|
||||
if (unlikely(!tal_resize(&parts, num+1)))
|
||||
goto fail;
|
||||
/* Ensure that tal_count() is correct. */
|
||||
if (unlikely(!tal_resize(&parts, num+1)))
|
||||
goto fail;
|
||||
|
||||
if (taken(delims))
|
||||
tal_free(delims);
|
||||
return parts;
|
||||
if (taken(delims))
|
||||
tal_free(delims);
|
||||
return parts;
|
||||
|
||||
fail:
|
||||
tal_free(parts);
|
||||
if (taken(delims))
|
||||
tal_free(delims);
|
||||
return NULL;
|
||||
tal_free(parts);
|
||||
if (taken(delims))
|
||||
tal_free(delims);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *tal_strjoin_(const tal_t *ctx,
|
||||
char *strings[], const char *delim, enum strjoin flags,
|
||||
const char *label)
|
||||
char *strings[], const char *delim, enum strjoin flags,
|
||||
const char *label)
|
||||
{
|
||||
unsigned int i;
|
||||
char *ret = NULL;
|
||||
size_t totlen = 0, dlen;
|
||||
unsigned int i;
|
||||
char *ret = NULL;
|
||||
size_t totlen = 0, dlen;
|
||||
|
||||
if (unlikely(!strings) && is_taken(strings))
|
||||
goto fail;
|
||||
if (unlikely(!strings) && is_taken(strings))
|
||||
goto fail;
|
||||
|
||||
if (unlikely(!delim) && is_taken(delim))
|
||||
goto fail;
|
||||
if (unlikely(!delim) && is_taken(delim))
|
||||
goto fail;
|
||||
|
||||
dlen = strlen(delim);
|
||||
ret = tal_arr_label(ctx, char, dlen*2+1, label);
|
||||
if (!ret)
|
||||
goto fail;
|
||||
dlen = strlen(delim);
|
||||
ret = tal_arr_label(ctx, char, dlen*2+1, label);
|
||||
if (!ret)
|
||||
goto fail;
|
||||
|
||||
ret[0] = '\0';
|
||||
for (i = 0; strings[i]; i++) {
|
||||
size_t len = strlen(strings[i]);
|
||||
ret[0] = '\0';
|
||||
for (i = 0; strings[i]; i++) {
|
||||
size_t len = strlen(strings[i]);
|
||||
|
||||
if (flags == STR_NO_TRAIL && !strings[i+1])
|
||||
dlen = 0;
|
||||
if (!tal_resize(&ret, totlen + len + dlen + 1))
|
||||
goto fail;
|
||||
memcpy(ret + totlen, strings[i], len);
|
||||
totlen += len;
|
||||
memcpy(ret + totlen, delim, dlen);
|
||||
totlen += dlen;
|
||||
}
|
||||
ret[totlen] = '\0';
|
||||
/* Make sure tal_count() is correct! */
|
||||
tal_resize(&ret, totlen+1);
|
||||
if (flags == STR_NO_TRAIL && !strings[i+1])
|
||||
dlen = 0;
|
||||
if (!tal_resize(&ret, totlen + len + dlen + 1))
|
||||
goto fail;
|
||||
memcpy(ret + totlen, strings[i], len);
|
||||
totlen += len;
|
||||
memcpy(ret + totlen, delim, dlen);
|
||||
totlen += dlen;
|
||||
}
|
||||
ret[totlen] = '\0';
|
||||
/* Make sure tal_count() is correct! */
|
||||
tal_resize(&ret, totlen+1);
|
||||
out:
|
||||
if (taken(strings))
|
||||
tal_free(strings);
|
||||
if (taken(delim))
|
||||
tal_free(delim);
|
||||
return ret;
|
||||
if (taken(strings))
|
||||
tal_free(strings);
|
||||
if (taken(delim))
|
||||
tal_free(delim);
|
||||
return ret;
|
||||
fail:
|
||||
ret = tal_free(ret);
|
||||
goto out;
|
||||
ret = tal_free(ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
static size_t count_open_braces(const char *string)
|
||||
{
|
||||
#if 1
|
||||
size_t num = 0, esc = 0;
|
||||
size_t num = 0, esc = 0;
|
||||
|
||||
while (*string) {
|
||||
if (*string == '\\')
|
||||
esc++;
|
||||
else {
|
||||
/* An odd number of \ means it's escaped. */
|
||||
if (*string == '(' && (esc & 1) == 0)
|
||||
num++;
|
||||
esc = 0;
|
||||
}
|
||||
string++;
|
||||
}
|
||||
return num;
|
||||
while (*string) {
|
||||
if (*string == '\\')
|
||||
esc++;
|
||||
else {
|
||||
/* An odd number of \ means it's escaped. */
|
||||
if (*string == '(' && (esc & 1) == 0)
|
||||
num++;
|
||||
esc = 0;
|
||||
}
|
||||
string++;
|
||||
}
|
||||
return num;
|
||||
#else
|
||||
return strcount(string, "(");
|
||||
return strcount(string, "(");
|
||||
#endif
|
||||
}
|
||||
|
||||
bool tal_strreg_(const tal_t *ctx, const char *string, const char *label,
|
||||
const char *regex, ...)
|
||||
const char *regex, ...)
|
||||
{
|
||||
size_t nmatch = 1 + count_open_braces(regex);
|
||||
regmatch_t matches[nmatch];
|
||||
regex_t r;
|
||||
bool ret = false;
|
||||
unsigned int i;
|
||||
va_list ap;
|
||||
size_t nmatch = 1 + count_open_braces(regex);
|
||||
regmatch_t matches[nmatch];
|
||||
regex_t r;
|
||||
bool ret = false;
|
||||
unsigned int i;
|
||||
va_list ap;
|
||||
|
||||
if (unlikely(!regex) && is_taken(regex))
|
||||
goto fail_no_re;
|
||||
if (unlikely(!regex) && is_taken(regex))
|
||||
goto fail_no_re;
|
||||
|
||||
if (regcomp(&r, regex, REG_EXTENDED) != 0)
|
||||
goto fail_no_re;
|
||||
if (regcomp(&r, regex, REG_EXTENDED) != 0)
|
||||
goto fail_no_re;
|
||||
|
||||
if (unlikely(!string) && is_taken(string))
|
||||
goto fail;
|
||||
if (unlikely(!string) && is_taken(string))
|
||||
goto fail;
|
||||
|
||||
if (regexec(&r, string, nmatch, matches, 0) != 0)
|
||||
goto fail;
|
||||
if (regexec(&r, string, nmatch, matches, 0) != 0)
|
||||
goto fail;
|
||||
|
||||
ret = true;
|
||||
va_start(ap, regex);
|
||||
for (i = 1; i < nmatch; i++) {
|
||||
char **arg = va_arg(ap, char **);
|
||||
if (arg) {
|
||||
/* eg. ([a-z])? can give "no match". */
|
||||
if (matches[i].rm_so == -1)
|
||||
*arg = NULL;
|
||||
else {
|
||||
*arg = tal_strndup_(ctx,
|
||||
string + matches[i].rm_so,
|
||||
matches[i].rm_eo
|
||||
- matches[i].rm_so,
|
||||
label);
|
||||
/* FIXME: If we fail, we set some and leak! */
|
||||
if (!*arg) {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
va_end(ap);
|
||||
ret = true;
|
||||
va_start(ap, regex);
|
||||
for (i = 1; i < nmatch; i++) {
|
||||
char **arg = va_arg(ap, char **);
|
||||
if (arg) {
|
||||
/* eg. ([a-z])? can give "no match". */
|
||||
if (matches[i].rm_so == -1)
|
||||
*arg = NULL;
|
||||
else {
|
||||
*arg = tal_strndup_(ctx,
|
||||
string + matches[i].rm_so,
|
||||
matches[i].rm_eo
|
||||
- matches[i].rm_so,
|
||||
label);
|
||||
/* FIXME: If we fail, we set some and leak! */
|
||||
if (!*arg) {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
va_end(ap);
|
||||
fail:
|
||||
regfree(&r);
|
||||
regfree(&r);
|
||||
fail_no_re:
|
||||
if (taken(regex))
|
||||
tal_free(regex);
|
||||
if (taken(string))
|
||||
tal_free(string);
|
||||
return ret;
|
||||
if (taken(regex))
|
||||
tal_free(regex);
|
||||
if (taken(string))
|
||||
tal_free(string);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#ifdef TAL_USE_TALLOC
|
||||
#include <ccan/tal/talloc/talloc.h>
|
||||
#else
|
||||
#include "ccan/tal/tal.h"
|
||||
#include <ccan/tal/tal.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
@@ -30,7 +30,7 @@ char *tal_strdup_(const tal_t *ctx, const char *p TAKES, const char *label);
|
||||
*/
|
||||
#define tal_strndup(ctx, p, n) tal_strndup_(ctx, p, n, TAL_LABEL(char, "[]"))
|
||||
char *tal_strndup_(const tal_t *ctx, const char *p TAKES, size_t n,
|
||||
const char *label);
|
||||
const char *label);
|
||||
|
||||
/**
|
||||
* tal_fmt - allocate a formatted string
|
||||
@@ -39,10 +39,10 @@ char *tal_strndup_(const tal_t *ctx, const char *p TAKES, size_t n,
|
||||
*
|
||||
* The returned string will have tal_count() == strlen() + 1.
|
||||
*/
|
||||
#define tal_fmt(ctx, ...) \
|
||||
tal_fmt_(ctx, TAL_LABEL(char, "[]"), __VA_ARGS__)
|
||||
#define tal_fmt(ctx, ...) \
|
||||
tal_fmt_(ctx, TAL_LABEL(char, "[]"), __VA_ARGS__)
|
||||
char *tal_fmt_(const tal_t *ctx, const char *label, const char *fmt TAKES,
|
||||
...) PRINTF_FMT(3,4);
|
||||
...) PRINTF_FMT(3,4);
|
||||
|
||||
/**
|
||||
* tal_vfmt - allocate a formatted string (va_list version)
|
||||
@@ -52,11 +52,11 @@ char *tal_fmt_(const tal_t *ctx, const char *label, const char *fmt TAKES,
|
||||
*
|
||||
* The returned string will have tal_count() == strlen() + 1.
|
||||
*/
|
||||
#define tal_vfmt(ctx, fmt, va) \
|
||||
tal_vfmt_(ctx, fmt, va, TAL_LABEL(char, "[]"))
|
||||
#define tal_vfmt(ctx, fmt, va) \
|
||||
tal_vfmt_(ctx, fmt, va, TAL_LABEL(char, "[]"))
|
||||
char *tal_vfmt_(const tal_t *ctx, const char *fmt TAKES, va_list ap,
|
||||
const char *label)
|
||||
PRINTF_FMT(2,0);
|
||||
const char *label)
|
||||
PRINTF_FMT(2,0);
|
||||
|
||||
/**
|
||||
* tal_append_fmt - append a formatted string to a talloc string.
|
||||
@@ -89,11 +89,11 @@ bool tal_append_vfmt(char **baseptr, const char *fmt TAKES, va_list ap);
|
||||
*/
|
||||
#define tal_strcat(ctx, s1, s2) tal_strcat_(ctx, s1, s2, TAL_LABEL(char, "[]"))
|
||||
char *tal_strcat_(const tal_t *ctx, const char *s1 TAKES, const char *s2 TAKES,
|
||||
const char *label);
|
||||
const char *label);
|
||||
|
||||
enum strsplit {
|
||||
STR_EMPTY_OK,
|
||||
STR_NO_EMPTY
|
||||
STR_EMPTY_OK,
|
||||
STR_NO_EMPTY
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -115,33 +115,33 @@ enum strsplit {
|
||||
* return the number of elements plus 1 (for that NULL).
|
||||
*
|
||||
* Example:
|
||||
* #include <ccan/tal/str/str.h>
|
||||
* ...
|
||||
* static unsigned int count_long_lines(const char *string)
|
||||
* {
|
||||
* char **lines;
|
||||
* unsigned int i, long_lines = 0;
|
||||
* #include <ccan/tal/str/str.h>
|
||||
* ...
|
||||
* static unsigned int count_long_lines(const char *string)
|
||||
* {
|
||||
* char **lines;
|
||||
* unsigned int i, long_lines = 0;
|
||||
*
|
||||
* // Can only fail on out-of-memory.
|
||||
* lines = tal_strsplit(NULL, string, "\n", STR_NO_EMPTY);
|
||||
* for (i = 0; lines[i] != NULL; i++)
|
||||
* if (strlen(lines[i]) > 80)
|
||||
* long_lines++;
|
||||
* tal_free(lines);
|
||||
* return long_lines;
|
||||
* }
|
||||
* // Can only fail on out-of-memory.
|
||||
* lines = tal_strsplit(NULL, string, "\n", STR_NO_EMPTY);
|
||||
* for (i = 0; lines[i] != NULL; i++)
|
||||
* if (strlen(lines[i]) > 80)
|
||||
* long_lines++;
|
||||
* tal_free(lines);
|
||||
* return long_lines;
|
||||
* }
|
||||
*/
|
||||
#define tal_strsplit(ctx, string, delims, flag) \
|
||||
tal_strsplit_(ctx, string, delims, flag, TAL_LABEL(char *, "[]"))
|
||||
#define tal_strsplit(ctx, string, delims, flag) \
|
||||
tal_strsplit_(ctx, string, delims, flag, TAL_LABEL(char *, "[]"))
|
||||
char **tal_strsplit_(const tal_t *ctx,
|
||||
const char *string TAKES,
|
||||
const char *delims TAKES,
|
||||
enum strsplit flag,
|
||||
const char *label);
|
||||
const char *string TAKES,
|
||||
const char *delims TAKES,
|
||||
enum strsplit flag,
|
||||
const char *label);
|
||||
|
||||
enum strjoin {
|
||||
STR_TRAIL,
|
||||
STR_NO_TRAIL
|
||||
STR_TRAIL,
|
||||
STR_NO_TRAIL
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -158,24 +158,24 @@ enum strjoin {
|
||||
* The returned string will have tal_count() == strlen() + 1.
|
||||
*
|
||||
* Example:
|
||||
* // Append the string "--EOL" to each line.
|
||||
* static char *append_to_all_lines(const char *string)
|
||||
* {
|
||||
* char **lines, *ret;
|
||||
* // Append the string "--EOL" to each line.
|
||||
* static char *append_to_all_lines(const char *string)
|
||||
* {
|
||||
* char **lines, *ret;
|
||||
*
|
||||
* lines = tal_strsplit(NULL, string, "\n", STR_EMPTY_OK);
|
||||
* ret = tal_strjoin(NULL, lines, "-- EOL\n", STR_TRAIL);
|
||||
* tal_free(lines);
|
||||
* return ret;
|
||||
* }
|
||||
* lines = tal_strsplit(NULL, string, "\n", STR_EMPTY_OK);
|
||||
* ret = tal_strjoin(NULL, lines, "-- EOL\n", STR_TRAIL);
|
||||
* tal_free(lines);
|
||||
* return ret;
|
||||
* }
|
||||
*/
|
||||
#define tal_strjoin(ctx, strings, delim, flags) \
|
||||
tal_strjoin_(ctx, strings, delim, flags, TAL_LABEL(char, "[]"))
|
||||
#define tal_strjoin(ctx, strings, delim, flags) \
|
||||
tal_strjoin_(ctx, strings, delim, flags, TAL_LABEL(char, "[]"))
|
||||
char *tal_strjoin_(const void *ctx,
|
||||
char *strings[] TAKES,
|
||||
const char *delim TAKES,
|
||||
enum strjoin flags,
|
||||
const char *label);
|
||||
char *strings[] TAKES,
|
||||
const char *delim TAKES,
|
||||
enum strjoin flags,
|
||||
const char *label);
|
||||
|
||||
/**
|
||||
* tal_strreg - match/extract from a string via (extended) regular expressions.
|
||||
@@ -196,30 +196,30 @@ char *tal_strjoin_(const void *ctx,
|
||||
* The allocated strings will have tal_count() == strlen() + 1.
|
||||
*
|
||||
* See Also:
|
||||
* regcomp(3), regex(3).
|
||||
* regcomp(3), regex(3).
|
||||
*
|
||||
* Example:
|
||||
* // Given "My name is Rusty" outputs "Hello Rusty!\n"
|
||||
* // Given "my first name is Rusty Russell" outputs "Hello Rusty Russell!\n"
|
||||
* // Given "My name isnt Rusty Russell" outputs "Hello there!\n"
|
||||
* int main(int argc, char *argv[])
|
||||
* {
|
||||
* char *person, *input;
|
||||
* // Given "My name is Rusty" outputs "Hello Rusty!\n"
|
||||
* // Given "my first name is Rusty Russell" outputs "Hello Rusty Russell!\n"
|
||||
* // Given "My name isnt Rusty Russell" outputs "Hello there!\n"
|
||||
* int main(int argc, char *argv[])
|
||||
* {
|
||||
* char *person, *input;
|
||||
*
|
||||
* (void)argc;
|
||||
* // Join args and trim trailing space.
|
||||
* input = tal_strjoin(NULL, argv+1, " ", STR_NO_TRAIL);
|
||||
* if (tal_strreg(NULL, input,
|
||||
* "[Mm]y (first )?name is ([A-Za-z ]+)",
|
||||
* NULL, &person))
|
||||
* printf("Hello %s!\n", person);
|
||||
* else
|
||||
* printf("Hello there!\n");
|
||||
* return 0;
|
||||
* }
|
||||
* (void)argc;
|
||||
* // Join args and trim trailing space.
|
||||
* input = tal_strjoin(NULL, argv+1, " ", STR_NO_TRAIL);
|
||||
* if (tal_strreg(NULL, input,
|
||||
* "[Mm]y (first )?name is ([A-Za-z ]+)",
|
||||
* NULL, &person))
|
||||
* printf("Hello %s!\n", person);
|
||||
* else
|
||||
* printf("Hello there!\n");
|
||||
* return 0;
|
||||
* }
|
||||
*/
|
||||
#define tal_strreg(ctx, string, ...) \
|
||||
tal_strreg_(ctx, string, TAL_LABEL(char, "[]"), __VA_ARGS__)
|
||||
#define tal_strreg(ctx, string, ...) \
|
||||
tal_strreg_(ctx, string, TAL_LABEL(char, "[]"), __VA_ARGS__)
|
||||
bool tal_strreg_(const void *ctx, const char *string TAKES,
|
||||
const char *label, const char *regex, ...);
|
||||
const char *label, const char *regex, ...);
|
||||
#endif /* CCAN_STR_TAL_H */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,12 @@
|
||||
/* Licensed under BSD-MIT - see LICENSE file for details */
|
||||
#ifndef CCAN_TAL_H
|
||||
#define CCAN_TAL_H
|
||||
#include "../config.h"
|
||||
#include "ccan/compiler/compiler.h"
|
||||
#include "ccan/likely/likely.h"
|
||||
#include "ccan/typesafe_cb/typesafe_cb.h"
|
||||
#include "ccan/str/str.h"
|
||||
#include "ccan/take/take.h"
|
||||
|
||||
#include "config.h"
|
||||
#include <ccan/compiler/compiler.h>
|
||||
#include <ccan/likely/likely.h>
|
||||
#include <ccan/typesafe_cb/typesafe_cb.h>
|
||||
#include <ccan/str/str.h>
|
||||
#include <ccan/take/take.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
@@ -32,11 +31,11 @@ typedef void tal_t;
|
||||
* tal_count() of the return will be 1.
|
||||
*
|
||||
* Example:
|
||||
* int *p = tal(NULL, int);
|
||||
* *p = 1;
|
||||
* int *p = tal(NULL, int);
|
||||
* *p = 1;
|
||||
*/
|
||||
#define tal(ctx, type) \
|
||||
tal_label(ctx, type, TAL_LABEL(type, ""))
|
||||
#define tal(ctx, type) \
|
||||
tal_label(ctx, type, TAL_LABEL(type, ""))
|
||||
|
||||
/**
|
||||
* talz - zeroing allocator function
|
||||
@@ -46,11 +45,11 @@ typedef void tal_t;
|
||||
* Equivalent to tal() followed by memset() to zero.
|
||||
*
|
||||
* Example:
|
||||
* p = talz(NULL, int);
|
||||
* assert(*p == 0);
|
||||
* p = talz(NULL, int);
|
||||
* assert(*p == 0);
|
||||
*/
|
||||
#define talz(ctx, type) \
|
||||
talz_label(ctx, type, TAL_LABEL(type, ""))
|
||||
#define talz(ctx, type) \
|
||||
talz_label(ctx, type, TAL_LABEL(type, ""))
|
||||
|
||||
/**
|
||||
* tal_free - free a tal-allocated pointer.
|
||||
@@ -64,7 +63,7 @@ typedef void tal_t;
|
||||
* for any destructors or notifiers.
|
||||
*
|
||||
* Example:
|
||||
* p = tal_free(p);
|
||||
* p = tal_free(p);
|
||||
*/
|
||||
void *tal_free(const tal_t *p);
|
||||
|
||||
@@ -77,12 +76,12 @@ void *tal_free(const tal_t *p);
|
||||
* tal_count() of the returned pointer will be @count.
|
||||
*
|
||||
* Example:
|
||||
* p = tal_arr(NULL, int, 2);
|
||||
* p[0] = 0;
|
||||
* p[1] = 1;
|
||||
* p = tal_arr(NULL, int, 2);
|
||||
* p[0] = 0;
|
||||
* p[1] = 1;
|
||||
*/
|
||||
#define tal_arr(ctx, type, count) \
|
||||
tal_arr_label(ctx, type, count, TAL_LABEL(type, "[]"))
|
||||
#define tal_arr(ctx, type, count) \
|
||||
tal_arr_label(ctx, type, count, TAL_LABEL(type, "[]"))
|
||||
|
||||
/**
|
||||
* tal_arrz - allocate an array of zeroed objects.
|
||||
@@ -93,11 +92,11 @@ void *tal_free(const tal_t *p);
|
||||
* Equivalent to tal_arr() followed by memset() to zero.
|
||||
*
|
||||
* Example:
|
||||
* p = tal_arrz(NULL, int, 2);
|
||||
* assert(p[0] == 0 && p[1] == 0);
|
||||
* p = tal_arrz(NULL, int, 2);
|
||||
* assert(p[0] == 0 && p[1] == 0);
|
||||
*/
|
||||
#define tal_arrz(ctx, type, count) \
|
||||
tal_arrz_label(ctx, type, count, TAL_LABEL(type, "[]"))
|
||||
tal_arrz_label(ctx, type, count, TAL_LABEL(type, "[]"))
|
||||
|
||||
/**
|
||||
* tal_resize - enlarge or reduce a tal object.
|
||||
@@ -111,10 +110,10 @@ void *tal_free(const tal_t *p);
|
||||
* has been moved.
|
||||
*
|
||||
* Example:
|
||||
* tal_resize(&p, 100);
|
||||
* tal_resize(&p, 100);
|
||||
*/
|
||||
#define tal_resize(p, count) \
|
||||
tal_resize_((void **)(p), sizeof**(p), (count), false)
|
||||
tal_resize_((void **)(p), sizeof**(p), (count), false)
|
||||
|
||||
/**
|
||||
* tal_resizez - enlarge or reduce a tal object; zero out extra.
|
||||
@@ -124,10 +123,10 @@ void *tal_free(const tal_t *p);
|
||||
* This returns true on success (and may move *@p), or false on failure.
|
||||
*
|
||||
* Example:
|
||||
* tal_resizez(&p, 200);
|
||||
* tal_resizez(&p, 200);
|
||||
*/
|
||||
#define tal_resizez(p, count) \
|
||||
tal_resize_((void **)(p), sizeof**(p), (count), true)
|
||||
tal_resize_((void **)(p), sizeof**(p), (count), true)
|
||||
|
||||
/**
|
||||
* tal_steal - change the parent of a tal-allocated pointer.
|
||||
@@ -141,10 +140,10 @@ void *tal_free(const tal_t *p);
|
||||
#if HAVE_STATEMENT_EXPR
|
||||
/* Weird macro avoids gcc's 'warning: value computed is not used'. */
|
||||
#define tal_steal(ctx, ptr) \
|
||||
({ (tal_typeof(ptr) tal_steal_((ctx),(ptr))); })
|
||||
({ (tal_typeof(ptr) tal_steal_((ctx),(ptr))); })
|
||||
#else
|
||||
#define tal_steal(ctx, ptr) \
|
||||
(tal_typeof(ptr) tal_steal_((ctx),(ptr)))
|
||||
(tal_typeof(ptr) tal_steal_((ctx),(ptr)))
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -157,8 +156,8 @@ void *tal_free(const tal_t *p);
|
||||
*
|
||||
* Note that this can only fail if your allocfn fails and your errorfn returns.
|
||||
*/
|
||||
#define tal_add_destructor(ptr, function) \
|
||||
tal_add_destructor_((ptr), typesafe_cb(void, void *, (function), (ptr)))
|
||||
#define tal_add_destructor(ptr, function) \
|
||||
tal_add_destructor_((ptr), typesafe_cb(void, void *, (function), (ptr)))
|
||||
|
||||
/**
|
||||
* tal_del_destructor - remove a destructor callback function.
|
||||
@@ -169,8 +168,8 @@ void *tal_free(const tal_t *p);
|
||||
* false. Note that if we're inside the destructor call itself, this will
|
||||
* return false.
|
||||
*/
|
||||
#define tal_del_destructor(ptr, function) \
|
||||
tal_del_destructor_((ptr), typesafe_cb(void, void *, (function), (ptr)))
|
||||
#define tal_del_destructor(ptr, function) \
|
||||
tal_del_destructor_((ptr), typesafe_cb(void, void *, (function), (ptr)))
|
||||
|
||||
/**
|
||||
* tal_add_destructor2 - add a 2-arg callback function when context is destroyed.
|
||||
@@ -184,13 +183,13 @@ void *tal_free(const tal_t *p);
|
||||
*
|
||||
* Note that this can only fail if your allocfn fails and your errorfn returns.
|
||||
*/
|
||||
#define tal_add_destructor2(ptr, function, arg) \
|
||||
tal_add_destructor2_((ptr), \
|
||||
typesafe_cb_cast(void (*)(tal_t *, void *), \
|
||||
void (*)(__typeof__(ptr), \
|
||||
__typeof__(arg)), \
|
||||
(function)), \
|
||||
(arg))
|
||||
#define tal_add_destructor2(ptr, function, arg) \
|
||||
tal_add_destructor2_((ptr), \
|
||||
typesafe_cb_cast(void (*)(tal_t *, void *), \
|
||||
void (*)(__typeof__(ptr), \
|
||||
__typeof__(arg)), \
|
||||
(function)), \
|
||||
(arg))
|
||||
|
||||
/**
|
||||
* tal_del_destructor - remove a destructor callback function.
|
||||
@@ -201,8 +200,8 @@ void *tal_free(const tal_t *p);
|
||||
* false. Note that if we're inside the destructor call itself, this will
|
||||
* return false.
|
||||
*/
|
||||
#define tal_del_destructor(ptr, function) \
|
||||
tal_del_destructor_((ptr), typesafe_cb(void, void *, (function), (ptr)))
|
||||
#define tal_del_destructor(ptr, function) \
|
||||
tal_del_destructor_((ptr), typesafe_cb(void, void *, (function), (ptr)))
|
||||
|
||||
/**
|
||||
* tal_del_destructor2 - remove 2-arg callback function.
|
||||
@@ -213,23 +212,23 @@ void *tal_free(const tal_t *p);
|
||||
* If @function has not been successfully added as a destructor with
|
||||
* @arg, this returns false.
|
||||
*/
|
||||
#define tal_del_destructor2(ptr, function, arg) \
|
||||
tal_del_destructor2_((ptr), \
|
||||
typesafe_cb_cast(void (*)(tal_t *, void *), \
|
||||
void (*)(__typeof__(ptr), \
|
||||
__typeof__(arg)), \
|
||||
(function)), \
|
||||
(arg))
|
||||
#define tal_del_destructor2(ptr, function, arg) \
|
||||
tal_del_destructor2_((ptr), \
|
||||
typesafe_cb_cast(void (*)(tal_t *, void *), \
|
||||
void (*)(__typeof__(ptr), \
|
||||
__typeof__(arg)), \
|
||||
(function)), \
|
||||
(arg))
|
||||
enum tal_notify_type {
|
||||
TAL_NOTIFY_FREE = 1,
|
||||
TAL_NOTIFY_STEAL = 2,
|
||||
TAL_NOTIFY_MOVE = 4,
|
||||
TAL_NOTIFY_RESIZE = 8,
|
||||
TAL_NOTIFY_RENAME = 16,
|
||||
TAL_NOTIFY_ADD_CHILD = 32,
|
||||
TAL_NOTIFY_DEL_CHILD = 64,
|
||||
TAL_NOTIFY_ADD_NOTIFIER = 128,
|
||||
TAL_NOTIFY_DEL_NOTIFIER = 256
|
||||
TAL_NOTIFY_FREE = 1,
|
||||
TAL_NOTIFY_STEAL = 2,
|
||||
TAL_NOTIFY_MOVE = 4,
|
||||
TAL_NOTIFY_RESIZE = 8,
|
||||
TAL_NOTIFY_RENAME = 16,
|
||||
TAL_NOTIFY_ADD_CHILD = 32,
|
||||
TAL_NOTIFY_DEL_CHILD = 64,
|
||||
TAL_NOTIFY_ADD_NOTIFIER = 128,
|
||||
TAL_NOTIFY_DEL_NOTIFIER = 256
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -270,23 +269,23 @@ enum tal_notify_type {
|
||||
* callback. This is also called for tal_add_destructor and
|
||||
* tal_del_destructor.
|
||||
*/
|
||||
#define tal_add_notifier(ptr, types, callback) \
|
||||
tal_add_notifier_((ptr), (types), \
|
||||
typesafe_cb_postargs(void, tal_t *, (callback), \
|
||||
(ptr), \
|
||||
enum tal_notify_type, void *))
|
||||
#define tal_add_notifier(ptr, types, callback) \
|
||||
tal_add_notifier_((ptr), (types), \
|
||||
typesafe_cb_postargs(void, tal_t *, (callback), \
|
||||
(ptr), \
|
||||
enum tal_notify_type, void *))
|
||||
|
||||
/**
|
||||
* tal_del_notifier - remove a notifier callback function.
|
||||
* @ptr: The tal allocated object.
|
||||
* @callback: the function to call.
|
||||
*/
|
||||
#define tal_del_notifier(ptr, callback) \
|
||||
tal_del_notifier_((ptr), \
|
||||
typesafe_cb_postargs(void, void *, (callback), \
|
||||
(ptr), \
|
||||
enum tal_notify_type, void *), \
|
||||
false, NULL)
|
||||
#define tal_del_notifier(ptr, callback) \
|
||||
tal_del_notifier_((ptr), \
|
||||
typesafe_cb_postargs(void, void *, (callback), \
|
||||
(ptr), \
|
||||
enum tal_notify_type, void *), \
|
||||
false, NULL)
|
||||
|
||||
/**
|
||||
* tal_set_name - attach a name to a tal pointer.
|
||||
@@ -295,7 +294,7 @@ enum tal_notify_type {
|
||||
*
|
||||
* The name is copied, unless we're certain it's a string literal.
|
||||
*/
|
||||
#define tal_set_name(ptr, name) \
|
||||
#define tal_set_name(ptr, name) \
|
||||
tal_set_name_((ptr), (name), TAL_IS_LITERAL(name))
|
||||
|
||||
/**
|
||||
@@ -355,8 +354,8 @@ tal_t *tal_parent(const tal_t *ctx);
|
||||
* @type: the type (should match type of @p!)
|
||||
* @p: the object to copy (or reparented if take()). Must not be NULL.
|
||||
*/
|
||||
#define tal_dup(ctx, type, p) \
|
||||
tal_dup_label(ctx, type, p, TAL_LABEL(type, ""), false)
|
||||
#define tal_dup(ctx, type, p) \
|
||||
tal_dup_label(ctx, type, p, TAL_LABEL(type, ""), false)
|
||||
|
||||
/**
|
||||
* tal_dup_or_null - duplicate an object, or just pass NULL.
|
||||
@@ -366,8 +365,8 @@ tal_t *tal_parent(const tal_t *ctx);
|
||||
*
|
||||
* if @p is NULL, just return NULL, otherwise to tal_dup().
|
||||
*/
|
||||
#define tal_dup_or_null(ctx, type, p) \
|
||||
tal_dup_label(ctx, type, p, TAL_LABEL(type, ""), true)
|
||||
#define tal_dup_or_null(ctx, type, p) \
|
||||
tal_dup_label(ctx, type, p, TAL_LABEL(type, ""), true)
|
||||
|
||||
/**
|
||||
* tal_dup_arr - duplicate an array.
|
||||
@@ -377,8 +376,8 @@ tal_t *tal_parent(const tal_t *ctx);
|
||||
* @n: the number of sizeof(type) entries to copy.
|
||||
* @extra: the number of extra sizeof(type) entries to allocate.
|
||||
*/
|
||||
#define tal_dup_arr(ctx, type, p, n, extra) \
|
||||
tal_dup_arr_label(ctx, type, p, n, extra, TAL_LABEL(type, "[]"))
|
||||
#define tal_dup_arr(ctx, type, p, n, extra) \
|
||||
tal_dup_arr_label(ctx, type, p, n, extra, TAL_LABEL(type, "[]"))
|
||||
|
||||
|
||||
/**
|
||||
@@ -387,28 +386,28 @@ tal_t *tal_parent(const tal_t *ctx);
|
||||
* @type: the type (should match type of @p!)
|
||||
* @p: the tal array to copy (or resized & reparented if take())
|
||||
*
|
||||
* The common case of duplicating an entire tal array.
|
||||
* The comon case of duplicating an entire tal array.
|
||||
*/
|
||||
#define tal_dup_talarr(ctx, type, p) \
|
||||
((type *)tal_dup_talarr_((ctx), tal_typechk_(p, type *), \
|
||||
TAL_LABEL(type, "[]")))
|
||||
#define tal_dup_talarr(ctx, type, p) \
|
||||
((type *)tal_dup_talarr_((ctx), tal_typechk_(p, type *), \
|
||||
TAL_LABEL(type, "[]")))
|
||||
/* Lower-level interfaces, where you want to supply your own label string. */
|
||||
#define tal_label(ctx, type, label) \
|
||||
((type *)tal_alloc_((ctx), sizeof(type), false, label))
|
||||
#define talz_label(ctx, type, label) \
|
||||
((type *)tal_alloc_((ctx), sizeof(type), true, label))
|
||||
#define tal_arr_label(ctx, type, count, label) \
|
||||
((type *)tal_alloc_arr_((ctx), sizeof(type), (count), false, label))
|
||||
#define tal_arrz_label(ctx, type, count, label) \
|
||||
((type *)tal_alloc_arr_((ctx), sizeof(type), (count), true, label))
|
||||
#define tal_dup_label(ctx, type, p, label, nullok) \
|
||||
((type *)tal_dup_((ctx), tal_typechk_(p, type *), \
|
||||
sizeof(type), 1, 0, nullok, \
|
||||
label))
|
||||
#define tal_dup_arr_label(ctx, type, p, n, extra, label) \
|
||||
((type *)tal_dup_((ctx), tal_typechk_(p, type *), \
|
||||
sizeof(type), (n), (extra), false, \
|
||||
label))
|
||||
#define tal_label(ctx, type, label) \
|
||||
((type *)tal_alloc_((ctx), sizeof(type), false, label))
|
||||
#define talz_label(ctx, type, label) \
|
||||
((type *)tal_alloc_((ctx), sizeof(type), true, label))
|
||||
#define tal_arr_label(ctx, type, count, label) \
|
||||
((type *)tal_alloc_arr_((ctx), sizeof(type), (count), false, label))
|
||||
#define tal_arrz_label(ctx, type, count, label) \
|
||||
((type *)tal_alloc_arr_((ctx), sizeof(type), (count), true, label))
|
||||
#define tal_dup_label(ctx, type, p, label, nullok) \
|
||||
((type *)tal_dup_((ctx), tal_typechk_(p, type *), \
|
||||
sizeof(type), 1, 0, nullok, \
|
||||
label))
|
||||
#define tal_dup_arr_label(ctx, type, p, n, extra, label) \
|
||||
((type *)tal_dup_((ctx), tal_typechk_(p, type *), \
|
||||
sizeof(type), (n), (extra), false, \
|
||||
label))
|
||||
|
||||
/**
|
||||
* tal_set_backend - set the allocation or error functions to use
|
||||
@@ -418,15 +417,15 @@ tal_t *tal_parent(const tal_t *ctx);
|
||||
* @error_fn: called on errors or NULL (default is abort)
|
||||
*
|
||||
* The defaults are set up so tal functions never return NULL, but you
|
||||
* can override error_fn to change that. error_fn can return, and is
|
||||
* can override erorr_fn to change that. error_fn can return, and is
|
||||
* called if alloc_fn or resize_fn fail.
|
||||
*
|
||||
* If any parameter is NULL, that function is unchanged.
|
||||
*/
|
||||
void tal_set_backend(void *(*alloc_fn)(size_t size),
|
||||
void *(*resize_fn)(void *, size_t size),
|
||||
void (*free_fn)(void *),
|
||||
void (*error_fn)(const char *msg));
|
||||
void *(*resize_fn)(void *, size_t size),
|
||||
void (*free_fn)(void *),
|
||||
void (*error_fn)(const char *msg));
|
||||
|
||||
/**
|
||||
* tal_expand - expand a tal array with contents.
|
||||
@@ -438,17 +437,17 @@ void tal_set_backend(void *(*alloc_fn)(size_t size),
|
||||
* be increased by @num2.
|
||||
*
|
||||
* Example:
|
||||
* int *arr1 = tal_arrz(NULL, int, 2);
|
||||
* int arr2[2] = { 1, 3 };
|
||||
* int *arr1 = tal_arrz(NULL, int, 2);
|
||||
* int arr2[2] = { 1, 3 };
|
||||
*
|
||||
* tal_expand(&arr1, arr2, 2);
|
||||
* assert(tal_count(arr1) == 4);
|
||||
* assert(arr1[2] == 1);
|
||||
* assert(arr1[3] == 3);
|
||||
* tal_expand(&arr1, arr2, 2);
|
||||
* assert(tal_count(arr1) == 4);
|
||||
* assert(arr1[2] == 1);
|
||||
* assert(arr1[3] == 3);
|
||||
*/
|
||||
#define tal_expand(a1p, a2, num2) \
|
||||
tal_expand_((void **)(a1p), (a2), sizeof**(a1p), \
|
||||
(num2) + 0*sizeof(*(a1p) == (a2)))
|
||||
#define tal_expand(a1p, a2, num2) \
|
||||
tal_expand_((void **)(a1p), (a2), sizeof**(a1p), \
|
||||
(num2) + 0*sizeof(*(a1p) == (a2)))
|
||||
|
||||
/**
|
||||
* tal_cleanup - remove pointers from NULL node
|
||||
@@ -472,7 +471,7 @@ void tal_cleanup(void);
|
||||
* when a problem is found, otherwise it is not.
|
||||
*
|
||||
* See also:
|
||||
* tal_set_backend()
|
||||
* tal_set_backend()
|
||||
*/
|
||||
bool tal_check(const tal_t *ctx, const char *errorstr);
|
||||
|
||||
@@ -493,7 +492,7 @@ void tal_dump(void);
|
||||
#else
|
||||
#ifdef CCAN_TAL_DEBUG
|
||||
#define TAL_LABEL(type, arr) \
|
||||
__FILE__ ":" stringify(__LINE__) ":" stringify(type) arr
|
||||
__FILE__ ":" stringify(__LINE__) ":" stringify(type) arr
|
||||
#else
|
||||
#define TAL_LABEL(type, arr) stringify(type) arr
|
||||
#endif /* CCAN_TAL_DEBUG */
|
||||
@@ -524,12 +523,12 @@ bool tal_set_name_(tal_t *ctx, const char *name, bool literal);
|
||||
|
||||
void *tal_alloc_(const tal_t *ctx, size_t bytes, bool clear, const char *label);
|
||||
void *tal_alloc_arr_(const tal_t *ctx, size_t bytes, size_t count, bool clear,
|
||||
const char *label);
|
||||
const char *label);
|
||||
|
||||
void *tal_dup_(const tal_t *ctx, const void *p TAKES, size_t size,
|
||||
size_t n, size_t extra, bool nullok, const char *label);
|
||||
size_t n, size_t extra, bool nullok, const char *label);
|
||||
void *tal_dup_talarr_(const tal_t *ctx, const tal_t *src TAKES,
|
||||
const char *label);
|
||||
const char *label);
|
||||
|
||||
tal_t *tal_steal_(const tal_t *new_parent, const tal_t *t);
|
||||
|
||||
@@ -538,16 +537,16 @@ bool tal_expand_(tal_t **ctxp, const void *src TAKES, size_t size, size_t count)
|
||||
|
||||
bool tal_add_destructor_(const tal_t *ctx, void (*destroy)(void *me));
|
||||
bool tal_add_destructor2_(const tal_t *ctx, void (*destroy)(void *me, void *arg),
|
||||
void *arg);
|
||||
void *arg);
|
||||
bool tal_del_destructor_(const tal_t *ctx, void (*destroy)(void *me));
|
||||
bool tal_del_destructor2_(const tal_t *ctx, void (*destroy)(void *me, void *arg),
|
||||
void *arg);
|
||||
void *arg);
|
||||
|
||||
bool tal_add_notifier_(const tal_t *ctx, enum tal_notify_type types,
|
||||
void (*notify)(tal_t *ctx, enum tal_notify_type,
|
||||
void *info));
|
||||
void (*notify)(tal_t *ctx, enum tal_notify_type,
|
||||
void *info));
|
||||
bool tal_del_notifier_(const tal_t *ctx,
|
||||
void (*notify)(tal_t *ctx, enum tal_notify_type,
|
||||
void *info),
|
||||
bool match_extra_arg, void *arg);
|
||||
void (*notify)(tal_t *ctx, enum tal_notify_type,
|
||||
void *info),
|
||||
bool match_extra_arg, void *arg);
|
||||
#endif /* CCAN_TAL_H */
|
||||
|
||||
Reference in New Issue
Block a user