Browse Source

Clean up extra ccan dirs.

Turns out that CCAN's create-ccan-tree has a bug with submodules.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 10 years ago
parent
commit
456a43c3b4
  1. 1
      ccan/ccan/str/hex/hex/LICENSE
  2. 39
      ccan/ccan/str/hex/hex/_info
  3. 70
      ccan/ccan/str/hex/hex/hex.c
  4. 73
      ccan/ccan/str/hex/hex/hex.h
  5. 42
      ccan/ccan/str/hex/hex/test/run.c
  6. 1
      ccan/ccan/tal/grab_file/grab_file/LICENSE
  7. 56
      ccan/ccan/tal/grab_file/grab_file/_info
  8. 64
      ccan/ccan/tal/grab_file/grab_file/grab_file.c
  9. 60
      ccan/ccan/tal/grab_file/grab_file/grab_file.h
  10. 37
      ccan/ccan/tal/grab_file/grab_file/test/run-grab.c
  11. 1
      ccan/ccan/tal/str/str/LICENSE
  12. 57
      ccan/ccan/tal/str/str/_info
  13. 312
      ccan/ccan/tal/str/str/str.c
  14. 186
      ccan/ccan/tal/str/str/str.h
  15. 22
      ccan/ccan/tal/str/str/test/helper.h
  16. 90
      ccan/ccan/tal/str/str/test/run-string.c
  17. 124
      ccan/ccan/tal/str/str/test/run-strreg.c
  18. 48
      ccan/ccan/tal/str/str/test/run-take.c
  19. 158
      ccan/ccan/tal/str/str/test/run.c
  20. 1
      ccan/ccan/tal/talloc/talloc/LICENSE
  21. 43
      ccan/ccan/tal/talloc/talloc/_info
  22. 263
      ccan/ccan/tal/talloc/talloc/talloc.c
  23. 316
      ccan/ccan/tal/talloc/talloc/talloc.h
  24. 46
      ccan/ccan/tal/talloc/talloc/test/run-array.c
  25. 33
      ccan/ccan/tal/talloc/talloc/test/run-count.c
  26. 67
      ccan/ccan/tal/talloc/talloc/test/run-destructor.c
  27. 35
      ccan/ccan/tal/talloc/talloc/test/run-expand.c
  28. 26
      ccan/ccan/tal/talloc/talloc/test/run-free.c
  29. 34
      ccan/ccan/tal/talloc/talloc/test/run-named-debug.c
  30. 30
      ccan/ccan/tal/talloc/talloc/test/run-named-nolabels.c
  31. 33
      ccan/ccan/tal/talloc/talloc/test/run-named.c
  32. 100
      ccan/ccan/tal/talloc/talloc/test/run-overflow.c
  33. 40
      ccan/ccan/tal/talloc/talloc/test/run-steal.c
  34. 56
      ccan/ccan/tal/talloc/talloc/test/run-take.c
  35. 44
      ccan/ccan/tal/talloc/talloc/test/run.c

1
ccan/ccan/str/hex/hex/LICENSE

@ -1 +0,0 @@
../../../licenses/CC0

39
ccan/ccan/str/hex/hex/_info

@ -1,39 +0,0 @@
#include "config.h"
#include <stdio.h>
#include <string.h>
/**
* str/hex - hex-to-string conversions and vice-versa
*
* This code contains simple routines for hexidecimal strings.
*
* License: CC0 (Public domain)
* Author: Rusty Russell <rusty@rustcorp.com.au>
*
* Example:
* int main(int argc, char *argv[])
* {
* int i;
*
* for (i = 1; i < argc; i++) {
* char str[hex_str_size(strlen(argv[i]))];
*
* hex_encode(str, sizeof(str), argv[i], strlen(argv[i]));
* printf("%s ", str);
* }
* printf("\n");
* return 0;
* }
*/
int main(int argc, char *argv[])
{
/* Expect exactly one argument */
if (argc != 2)
return 1;
if (strcmp(argv[1], "depends") == 0) {
return 0;
}
return 1;
}

70
ccan/ccan/str/hex/hex/hex.c

@ -1,70 +0,0 @@
/* CC0 license (public domain) - see LICENSE file for details */
#include <ccan/str/hex/hex.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
static bool char_to_hex(unsigned char *val, char c)
{
if (c >= '0' && c <= '9') {
*val = c - '0';
return true;
}
if (c >= 'a' && c <= 'f') {
*val = c - 'a' + 10;
return true;
}
if (c >= 'A' && c <= 'F') {
*val = c - 'A' + 10;
return true;
}
return false;
}
bool hex_decode(const char *str, size_t slen, void *buf, size_t bufsize)
{
unsigned char v1, v2;
unsigned char *p = buf;
while (slen > 1) {
if (!char_to_hex(&v1, str[0]) || !char_to_hex(&v2, str[1]))
return false;
if (!bufsize)
return false;
*(p++) = (v1 << 4) | v2;
str += 2;
slen -= 2;
bufsize--;
}
return slen == 0 && bufsize == 0;
}
static char hexchar(unsigned int val)
{
if (val < 10)
return '0' + val;
if (val < 16)
return 'a' + val - 10;
abort();
}
bool hex_encode(const void *buf, size_t bufsize, char *dest, size_t destsize)
{
size_t used = 0;
if (destsize < 1)
return false;
while (used < bufsize) {
unsigned int c = ((const unsigned char *)buf)[used];
if (destsize < 3)
return false;
*(dest++) = hexchar(c >> 4);
*(dest++) = hexchar(c & 0xF);
used++;
destsize -= 2;
}
*dest = '\0';
return used + 1;
}

73
ccan/ccan/str/hex/hex/hex.h

@ -1,73 +0,0 @@
/* CC0 (Public domain) - see LICENSE file for details */
#ifndef CCAN_HEX_H
#define CCAN_HEX_H
#include "config.h"
#include <stdbool.h>
#include <stdlib.h>
/**
* hex_decode - Unpack a hex string.
* @str: the hexidecimal string
* @slen: the length of @str
* @buf: the buffer to write the data into
* @bufsize: the length of @buf
*
* Returns false if there are any characters which aren't 0-9, a-f or A-F,
* of the string wasn't the right length for @bufsize.
*
* Example:
* unsigned char data[20];
*
* if (!hex_decode(argv[1], strlen(argv[1]), data, 20))
* printf("String is malformed!\n");
*/
bool hex_decode(const char *str, size_t slen, void *buf, size_t bufsize);
/**
* hex_encode - Create a nul-terminated hex string
* @buf: the buffer to read the data from
* @bufsize: the length of @buf
* @dest: the string to fill
* @destsize: the max size of the string
*
* Returns true if the string, including terminator, fit in @destsize;
*
* Example:
* unsigned char buf[] = { 0x1F, 0x2F };
* char str[5];
*
* if (!hex_encode(buf, sizeof(buf), str, sizeof(str)))
* abort();
*/
bool hex_encode(const void *buf, size_t bufsize, char *dest, size_t destsize);
/**
* hex_str_size - Calculate how big a nul-terminated hex string is
* @bytes: bytes of data to represent
*
* Example:
* unsigned char buf[] = { 0x1F, 0x2F };
* char str[hex_str_size(sizeof(buf))];
*
* hex_encode(buf, sizeof(buf), str, sizeof(str));
*/
static inline size_t hex_str_size(size_t bytes)
{
return 2 * bytes + 1;
}
/**
* hex_data_size - Calculate how many bytes of data in a hex string
* @strlen: the length of the string (with or without NUL)
*
* Example:
* const char str[] = "1F2F";
* unsigned char buf[hex_data_size(sizeof(str))];
*
* hex_decode(str, strlen(str), buf, sizeof(buf));
*/
static inline size_t hex_data_size(size_t strlen)
{
return strlen / 2;
}
#endif /* PETTYCOIN_HEX_H */

42
ccan/ccan/str/hex/hex/test/run.c

@ -1,42 +0,0 @@
#include <ccan/str/hex/hex.h>
/* Include the C files directly. */
#include <ccan/str/hex/hex.c>
#include <ccan/tap/tap.h>
#include <string.h>
int main(void)
{
const char teststr[] = "0123456789abcdefABCDEF";
const char bad_teststr[] = "0123456789abcdefABCDEF1O";
const unsigned char testdata[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
0xcd, 0xef, 0xAB, 0xCD, 0xEF };
unsigned char data[11];
char str[23];
size_t i;
plan_tests(10 + sizeof(str));
ok1(hex_str_size(sizeof(testdata)) == sizeof(teststr));
/* This gives right result with or without nul included */
ok1(hex_data_size(strlen(teststr)) == sizeof(testdata));
ok1(hex_data_size(sizeof(teststr)) == sizeof(testdata));
ok1(hex_decode(teststr, strlen(teststr), data, sizeof(data)));
ok1(memcmp(data, testdata, sizeof(testdata)) == 0);
ok1(hex_encode(testdata, sizeof(testdata), str, sizeof(str)));
ok1(strcmp(str, "0123456789abcdefabcdef") == 0);
/* Bad char */
ok1(!hex_decode(bad_teststr, strlen(bad_teststr), data, sizeof(data)));
/* Bad hex string len */
ok1(!hex_decode(teststr, strlen(teststr) - 1, data, sizeof(data)));
/* Bad buffer len */
ok1(!hex_decode(teststr, strlen(teststr), data, sizeof(data) - 1));
/* Bad deststring size. */
for (i = 1; i <= sizeof(str); i++)
ok1(!hex_encode(testdata, sizeof(testdata), str, sizeof(str)-i));
/* This exits depending on whether all tests passed */
return exit_status();
}

1
ccan/ccan/tal/grab_file/grab_file/LICENSE

@ -1 +0,0 @@
../../../licenses/LGPL-2.1

56
ccan/ccan/tal/grab_file/grab_file/_info

@ -1,56 +0,0 @@
#include "config.h"
#include <stdio.h>
#include <string.h>
/**
* tal/grab_file - file helper routines
*
* This contains simple functions for getting the contents of a file.
*
* Example:
* #include <err.h>
* #include <stdio.h>
* #include <string.h>
* #include <ccan/tal/grab_file/grab_file.h>
* #include <ccan/tal/tal.h> // for tal_free
*
* int main(int argc, char *argv[])
* {
* char *file;
*
* file = grab_file(NULL, argv[1]);
* if (!file)
* err(1, "Could not read file %s", argv[1]);
* if (strlen(file)+1 != tal_count(file))
* printf("File contains NUL characters\n");
* else if (tal_count(file) == 1)
* printf("File contains nothing\n");
* else if (strchr(file, '\n'))
* printf("File contains multiple lines\n");
* else
* printf("File contains one line\n");
* tal_free(file);
*
* return 0;
* }
*
* License: LGPL (v2.1 or any later version)
* 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/tal\n");
printf("ccan/noerr\n");
return 0;
}
if (strcmp(argv[1], "testdepends") == 0) {
printf("ccan/tal/str\n");
return 0;
}
return 1;
}

64
ccan/ccan/tal/grab_file/grab_file/grab_file.c

@ -1,64 +0,0 @@
/* Licensed under LGPLv2+ - see LICENSE file for details */
#include "grab_file.h"
#include <ccan/tal/tal.h>
#include <ccan/noerr/noerr.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void *grab_fd(const void *ctx, int fd)
{
int ret;
size_t max, size;
char *buffer;
struct stat st;
size = 0;
if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode))
max = st.st_size;
else
max = 16384;
buffer = tal_arr(ctx, char, max+1);
while ((ret = read(fd, buffer + size, max - size)) > 0) {
size += ret;
if (size == max) {
size_t extra = max;
if (extra > 1024 * 1024)
extra = 1024 * 1024;
if (!tal_resize(&buffer, max+extra+1))
return NULL;
max += extra;
}
}
if (ret < 0)
buffer = tal_free(buffer);
else {
buffer[size] = '\0';
tal_resize(&buffer, size+1);
}
return buffer;
}
void *grab_file(const void *ctx, const char *filename)
{
int fd;
char *buffer;
if (!filename)
fd = dup(STDIN_FILENO);
else
fd = open(filename, O_RDONLY, 0);
if (fd < 0)
return NULL;
buffer = grab_fd(ctx, fd);
close_noerr(fd);
return buffer;
}

60
ccan/ccan/tal/grab_file/grab_file/grab_file.h

@ -1,60 +0,0 @@
/* Licensed under LGPLv2+ - see LICENSE file for details */
#ifndef CCAN_TAL_GRAB_FILE_H
#define CCAN_TAL_GRAB_FILE_H
#include <stdio.h> // For size_t
/**
* grab_fd - read all of a file descriptor into memory
* @ctx: the context to tallocate from (often NULL)
* @fd: the file descriptor to read from
*
* This function reads from the given file descriptor until no more
* input is available. The content is talloced off @ctx, and the
* tal_count() is the size in bytes plus one: for convenience, the
* byte after the end of the content will always be NUL.
*
* Example:
* #include <ccan/tal/str/str.h>
* #include <ccan/tal/tal.h>
* ...
* // Return all of standard input, as lines.
* static char **read_stdin_as_lines(void)
* {
* char **lines, *all;
*
* all = grab_fd(NULL, 0);
* if (!all)
* return NULL;
* lines = tal_strsplit(NULL, all, "\n", STR_EMPTY_OK);
* tal_free(all);
* return lines;
* }
*/
void *grab_fd(const void *ctx, int fd);
/**
* grab_file - read all of a file (or stdin) into memory
* @ctx: the context to tallocate from (often NULL)
* @filename: the file to read (NULL for stdin)
*
* This function reads from the given file until no more input is
* available. The content is talloced off @ctx, and the tal_count()
* is the size in bytes plus one: for convenience, the byte after the
* end of the content will always be NUL.
*
* Example:
* // Return all of a given file, as lines.
* static char **read_file_as_lines(const char *filename)
* {
* char **lines, *all;
*
* all = grab_file(NULL, filename);
* if (!all)
* return NULL;
* lines = tal_strsplit(NULL, all, "\n", STR_EMPTY_OK);
* tal_free(all);
* return lines;
* }
*/
void *grab_file(const void *ctx, const char *filename);
#endif /* CCAN_TAL_GRAB_FILE_H */

37
ccan/ccan/tal/grab_file/grab_file/test/run-grab.c

@ -1,37 +0,0 @@
/* This is test for grab_file() function
*/
#include <ccan/tal/grab_file/grab_file.h>
#include <stdlib.h>
#include <stdio.h>
#include <err.h>
#include <sys/stat.h>
#include <ccan/tal/grab_file/grab_file.c>
#include <ccan/tap/tap.h>
#include <ccan/tal/str/str.h>
int
main(int argc, char *argv[])
{
unsigned int i;
char **split, *str;
int length;
struct stat st;
str = grab_file(NULL, "test/run-grab.c");
split = tal_strsplit(str, str, "\n", STR_EMPTY_OK);
length = strlen(split[0]);
ok1(!strcmp(split[0], "/* This is test for grab_file() function"));
for (i = 1; split[i]; i++)
length += strlen(split[i]);
ok1(!strcmp(split[i-1], "/* End of grab_file() test */"));
if (stat("test/run-grab.c", &st) != 0)
/* FIXME: ditto */
if (stat("ccan/tal/grab_file/test/run-grab.c", &st) != 0)
err(1, "Could not stat self");
ok1(st.st_size == length + i);
tal_free(str);
return 0;
}
/* End of grab_file() test */

1
ccan/ccan/tal/str/str/LICENSE

@ -1 +0,0 @@
../../../licenses/BSD-MIT

57
ccan/ccan/tal/str/str/_info

@ -1,57 +0,0 @@
#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".
*
* 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;
*
* // 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;
}

312
ccan/ccan/tal/str/str/str.c

@ -1,312 +0,0 @@
/* Licensed under BSD-MIT - see LICENSE file for details */
#include <unistd.h>
#include <stdint.h>
#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 <ccan/str/str.h>
#include <ccan/take/take.h>
char *tal_strdup(const tal_t *ctx, const char *p)
{
/* We have to let through NULL for take(). */
return tal_dup_(ctx, p, 1, p ? strlen(p) + 1: 1, 0, false,
TAL_LABEL(char, "[]"));
}
char *tal_strndup(const tal_t *ctx, const char *p, size_t n)
{
size_t len;
char *ret;
/* We have to let through NULL for take(). */
if (likely(p)) {
len = strlen(p);
if (len > n)
len = n;
} else
len = n;
ret = tal_dup_(ctx, p, 1, len, 1, false, TAL_LABEL(char, "[]"));
if (ret)
ret[len] = '\0';
return ret;
}
char *tal_fmt(const tal_t *ctx, const char *fmt, ...)
{
va_list ap;
char *ret;
va_start(ap, fmt);
ret = tal_vfmt(ctx, fmt, ap);
va_end(ap);
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;
bool ok;
for (;;) {
va_list ap2;
int ret;
if (!tal_resize(buf, off + max)) {
ok = false;
break;
}
va_copy(ap2, ap);
ret = vsnprintf(*buf + off, max, fmt, ap2);
va_end(ap2);
if (ret < max) {
ok = true;
break;
}
max *= 2;
}
if (taken(fmt))
tal_free(fmt);
return ok;
}
char *tal_vfmt(const tal_t *ctx, const char *fmt, va_list ap)
{
char *buf;
if (!fmt && taken(fmt))
return NULL;
/* A decent guess to start. */
buf = tal_arr(ctx, char, strlen(fmt) * 2);
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;
return do_vfmt(baseptr, strlen(*baseptr), fmt, ap);
}
bool tal_append_fmt(char **baseptr, const char *fmt, ...)
{
va_list ap;
bool ret;
va_start(ap, fmt);
ret = tal_append_vfmt(baseptr, fmt, ap);
va_end(ap);
return ret;
}
char *tal_strcat(const tal_t *ctx, const char *s1, const char *s2)
{
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);
/* We use tal_dup_ here to avoid attaching a length property. */
ret = tal_dup_(ctx, s1, 1, len1, len2 + 1, false,
TAL_LABEL(char, "[]"));
if (likely(ret))
memcpy(ret + len1, s2, len2 + 1);
if (taken(s2))
tal_free(s2);
return ret;
}
char **tal_strsplit(const tal_t *ctx,
const char *string, const char *delims, enum strsplit flags)
{
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;
if (flags == STR_NO_EMPTY)
str += strspn(str, delims);
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;
/* Ensure that tal_count() is correct. */
if (unlikely(!tal_resize(&parts, num+1)))
goto fail;
if (taken(delims))
tal_free(delims);
return parts;
fail:
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)
{
unsigned int i;
char *ret = NULL;
size_t totlen = 0, dlen;
if (unlikely(!strings) && is_taken(strings))
goto fail;
if (unlikely(!delim) && is_taken(delim))
goto fail;
dlen = strlen(delim);
ret = tal_arr(ctx, char, dlen*2+1);
if (!ret)
goto fail;
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';
out:
if (taken(strings))
tal_free(strings);
if (taken(delim))
tal_free(delim);
return ret;
fail:
ret = tal_free(ret);
goto out;
}
static size_t count_open_braces(const char *string)
{
#if 1
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;
#else
return strcount(string, "(");
#endif
}
bool tal_strreg(const tal_t *ctx, const char *string, 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;
if (unlikely(!regex) && is_taken(regex))
goto fail_no_re;
if (regcomp(&r, regex, REG_EXTENDED) != 0)
goto fail_no_re;
if (unlikely(!string) && is_taken(string))
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);
/* FIXME: If we fail, we set some and leak! */
if (!*arg) {
ret = false;
break;
}
}
}
}
va_end(ap);
fail:
regfree(&r);
fail_no_re:
if (taken(regex))
tal_free(regex);
if (taken(string))
tal_free(string);
return ret;
}

186
ccan/ccan/tal/str/str/str.h

@ -1,186 +0,0 @@
/* Licensed under BSD-MIT - see LICENSE file for details */
#ifndef CCAN_STR_TAL_H
#define CCAN_STR_TAL_H
#ifdef TAL_USE_TALLOC
#include <ccan/tal/talloc/talloc.h>
#else
#include <ccan/tal/tal.h>
#endif
#include <string.h>
#include <stdbool.h>
/**
* tal_strdup - duplicate a string
* @ctx: NULL, or tal allocated object to be parent.
* @p: the string to copy (can be take()).
*/
char *tal_strdup(const tal_t *ctx, const char *p);
/**
* tal_strndup - duplicate a limited amount of a string.
* @ctx: NULL, or tal allocated object to be parent.
* @p: the string to copy (can be take()).
* @n: the maximum length to copy.
*
* Always gives a nul-terminated string, with strlen() <= @n.
*/
char *tal_strndup(const tal_t *ctx, const char *p, size_t n);
/**
* tal_fmt - allocate a formatted string
* @ctx: NULL, or tal allocated object to be parent.
* @fmt: the printf-style format (can be take()).
*/
char *tal_fmt(const tal_t *ctx, const char *fmt, ...) PRINTF_FMT(2,3);
/**
* tal_vfmt - allocate a formatted string (va_list version)
* @ctx: NULL, or tal allocated object to be parent.
* @fmt: the printf-style format (can be take()).
* @va: the va_list containing the format args.
*/
char *tal_vfmt(const tal_t *ctx, const char *fmt, va_list ap)
PRINTF_FMT(2,0);
/**
* tal_append_fmt - append a formatted string to a talloc string.
* @baseptr: a pointer to the tal string to be appended to.
* @fmt: the printf-style format (can be take()).
*
* Returns false on allocation failure.
*/
bool tal_append_fmt(char **baseptr, const char *fmt, ...) PRINTF_FMT(2,3);
/**
* tal_append_vfmt - append a formatted string to a talloc string (va_list)
* @baseptr: a pointer to the tal string to be appended to.
* @fmt: the printf-style format (can be take()).
* @va: the va_list containing the format args.
*
* Returns false on allocation failure.
*/
bool tal_append_vfmt(char **baseptr, const char *fmt, va_list ap);
/**
* tal_strcat - join two strings together
* @ctx: NULL, or tal allocated object to be parent.
* @s1: the first string (can be take()).
* @s2: the second string (can be take()).
*/
char *tal_strcat(const tal_t *ctx, const char *s1, const char *s2);
enum strsplit {
STR_EMPTY_OK,
STR_NO_EMPTY
};
/**
* tal_strsplit - Split string into an array of substrings
* @ctx: the context to tal from (often NULL).
* @string: the string to split (can be take()).
* @delims: delimiters where lines should be split (can be take()).
* @flags: whether to include empty substrings.
*
* This function splits a single string into multiple strings.
*
* If @string is take(), the returned array will point into the
* mangled @string.
*
* Multiple delimiters result in empty substrings. By definition, no
* delimiters will appear in the substrings.
*
* The final char * in the array will be NULL, and tal_count() will
* 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;
*
* // 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;
* }
*/
char **tal_strsplit(const tal_t *ctx,
const char *string, const char *delims, enum strsplit flag);
enum strjoin {
STR_TRAIL,
STR_NO_TRAIL
};
/**
* tal_strjoin - Join an array of substrings into one long string
* @ctx: the context to tal from (often NULL).
* @strings: the NULL-terminated array of strings to join (can be take())
* @delim: the delimiter to insert between the strings (can be take())
* @flags: whether to add a delimieter to the end
*
* This function joins an array of strings into a single string. The
* return value is allocated using tal. Each string in @strings is
* followed by a copy of @delim.
*
* Example:
* // 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;
* }
*/
char *tal_strjoin(const void *ctx, char *strings[], const char *delim,
enum strjoin flags);
/**
* tal_strreg - match/extract from a string via (extended) regular expressions.
* @ctx: the context to tal from (often NULL)
* @string: the string to try to match (can be take())
* @regex: the regular expression to match (can be take())
* ...: pointers to strings to allocate for subexpressions.
*
* Returns true if we matched, in which case any parenthesized
* expressions in @regex are allocated and placed in the char **
* arguments following @regex. NULL arguments mean the match is not
* saved. The order of the strings is the order
* of opening braces in the expression: in the case of repeated
* expressions (eg "([a-z])*") the last one is saved, in the case of
* non-existent matches (eg "([a-z]*)?") the pointer is set to NULL.
*
* Allocation failures or malformed regular expressions return false.
*
* See Also:
* regcomp(3), regex(3).
*
* Example:
* // Given 'My name is Rusty' outputs 'Hello Rusty!'
* // Given 'my first name is Rusty Russell' outputs 'Hello Rusty Russell!'
* // Given 'My name isnt Rusty Russell' outputs 'Hello there!'
* int main(int argc, char *argv[])
* {
* char *person, *input;
*
* // 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;
* }
*/
bool tal_strreg(const void *ctx, const char *string, const char *regex, ...);
#endif /* CCAN_STR_TAL_H */

22
ccan/ccan/tal/str/str/test/helper.h

@ -1,22 +0,0 @@
/* tal/talloc can't implement tal_first/tal_next. */
#ifdef TAL_USE_TALLOC
static inline bool no_children(const void *ctx)
{
return talloc_total_blocks(ctx) == 1;
}
static inline bool single_child(const void *ctx, const void *child)
{
return talloc_total_blocks(ctx) == 2 && tal_parent(child) == ctx;
}
#else
static inline bool no_children(const void *ctx)
{
return !tal_first(ctx);
}
static inline bool single_child(const void *ctx, const void *child)
{
return tal_first(ctx) == child && !tal_next(ctx, child);
}
#endif

90
ccan/ccan/tal/str/str/test/run-string.c

@ -1,90 +0,0 @@
#include <ccan/tal/str/str.h>
#include <ccan/tal/str/str.c>
#include <ccan/tap/tap.h>
#include "helper.h"
int main(void)
{
char *parent, *c;
plan_tests(32);
parent = tal(NULL, char);
ok1(parent);
c = tal_strdup(parent, "hello");
ok1(strcmp(c, "hello") == 0);
ok1(tal_parent(c) == parent);
tal_free(c);
c = tal_strndup(parent, "hello", 3);
ok1(strcmp(c, "hel") == 0);
ok1(tal_parent(c) == parent);
tal_free(c);
#ifdef TAL_USE_TALLOC
c = tal_talloc_typechk_(parent, char *);
#else
c = tal_typechk_(parent, char *);
#endif
c = tal_dup_arr(parent, char, "hello", 6, 0);
ok1(strcmp(c, "hello") == 0);
ok1(strcmp(tal_name(c), "char[]") == 0);
ok1(tal_parent(c) == parent);
tal_free(c);
/* Now with an extra byte. */
c = tal_dup_arr(parent, char, "hello", 6, 1);
ok1(strcmp(c, "hello") == 0);
ok1(strcmp(tal_name(c), "char[]") == 0);
ok1(tal_parent(c) == parent);
strcat(c, "x");
tal_free(c);
c = tal_fmt(parent, "hello %s", "there");
ok1(strcmp(c, "hello there") == 0);
ok1(tal_parent(c) == parent);
tal_free(c);
c = tal_strcat(parent, "hello ", "there");
ok1(strcmp(c, "hello there") == 0);
ok1(tal_parent(c) == parent);
/* Make sure take works correctly. */
c = tal_strcat(parent, take(c), " again");
ok1(strcmp(c, "hello there again") == 0);
ok1(tal_parent(c) == parent);
ok1(single_child(parent, c));
c = tal_strcat(parent, "And ", take(c));
ok1(strcmp(c, "And hello there again") == 0);
ok1(tal_parent(c) == parent);
ok1(single_child(parent, c));
/* NULL pass through works... */
c = tal_strcat(parent, take(NULL), take(c));
ok1(!c);
ok1(no_children(parent));
c = tal_strcat(parent, take(tal_strdup(parent, "hi")),
take(NULL));
ok1(!c);
ok1(no_children(parent));
c = tal_strcat(parent, take(NULL), take(NULL));
ok1(!c);
ok1(no_children(parent));
/* Appending formatted strings. */
c = tal_strdup(parent, "hi");
ok1(tal_append_fmt(&c, "%s %s", "there", "world"));
ok1(strcmp(c, "hithere world") == 0);
ok1(tal_parent(c) == parent);
ok1(!tal_append_fmt(&c, take(NULL), "there", "world"));
ok1(strcmp(c, "hithere world") == 0);
tal_free(parent);
return exit_status();
}

124
ccan/ccan/tal/str/str/test/run-strreg.c

@ -1,124 +0,0 @@
#include <ccan/tal/str/str.h>
#include <ccan/tal/str/str.c>
#include <ccan/tap/tap.h>
#include "helper.h"
static bool find_parent(tal_t *child, tal_t *parent)
{
tal_t *i;
for (i = child; i; i = tal_parent(i))
if (i == parent)
return true;
return false;
}
int main(int argc, char *argv[])
{
void *ctx = tal_strdup(NULL, "toplevel");
char *a, *b;
/* If it accesses this, it will crash. */
char **invalid = (char **)1L;
plan_tests(41);
/* Simple matching. */
ok1(tal_strreg(ctx, "hello world!", "hello") == true);
ok1(tal_strreg(ctx, "hello world!", "hi") == false);
/* No parentheses means we don't use any extra args. */
ok1(tal_strreg(ctx, "hello world!", "hello", invalid) == true);
ok1(tal_strreg(ctx, "hello world!", "hi", invalid) == false);
ok1(tal_strreg(ctx, "hello world!", "[a-z]+", invalid) == true);
ok1(tal_strreg(ctx, "hello world!", "([a-z]+)", &a, invalid) == true);
/* Found string */
ok1(streq(a, "hello"));
/* Allocated off ctx */
ok1(find_parent(a, ctx));
tal_free(a);
ok1(tal_strreg(ctx, "hello world!", "([a-z]*) ([a-z]+)",
&a, &b, invalid) == true);
ok1(streq(a, "hello"));
ok1(streq(b, "world"));
ok1(find_parent(a, ctx));
ok1(find_parent(b, ctx));
tal_free(a);
tal_free(b);
/* * after parentheses returns last match. */
ok1(tal_strreg(ctx, "hello world!", "([a-z])* ([a-z]+)",
&a, &b, invalid) == true);
ok1(streq(a, "o"));
ok1(streq(b, "world"));
tal_free(a);
tal_free(b);
/* Nested parentheses are ordered by open brace. */
ok1(tal_strreg(ctx, "hello world!", "(([a-z]*) world)",
&a, &b, invalid) == true);
ok1(streq(a, "hello world"));
ok1(streq(b, "hello"));
tal_free(a);
tal_free(b);
/* Nested parentheses are ordered by open brace. */
ok1(tal_strreg(ctx, "hello world!", "(([a-z]*) world)",
&a, &b, invalid) == true);
ok1(streq(a, "hello world"));
ok1(streq(b, "hello"));
tal_free(a);
tal_free(b);
/* NULL means we're not interested. */
ok1(tal_strreg(ctx, "hello world!", "((hello|goodbye) world)",
&a, NULL, invalid) == true);
ok1(streq(a, "hello world"));
tal_free(a);
/* No leaks! */
ok1(no_children(ctx));
/* NULL arg with take means always fail. */
ok1(tal_strreg(ctx, take(NULL), "((hello|goodbye) world)",
&b, NULL, invalid) == false);
/* Take string. */
a = tal_strdup(ctx, "hello world!");
ok1(tal_strreg(ctx, take(a), "([a-z]+)", &b, invalid) == true);
ok1(streq(b, "hello"));
ok1(tal_parent(b) == ctx);
tal_free(b);
ok1(no_children(ctx));
/* Take regex. */
a = tal_strdup(ctx, "([a-z]+)");
ok1(tal_strreg(ctx, "hello world!", take(a), &b, invalid) == true);
ok1(streq(b, "hello"));
ok1(tal_parent(b) == ctx);
tal_free(b);
ok1(no_children(ctx));
/* Take both. */
a = tal_strdup(ctx, "([a-z]+)");
ok1(tal_strreg(ctx, take(tal_strdup(ctx, "hello world!")),
take(a), &b, invalid) == true);
ok1(streq(b, "hello"));
ok1(tal_parent(b) == ctx);
tal_free(b);
ok1(no_children(ctx));
/* ... even if we fail to match. */
a = tal_strdup(ctx, "([a-z]+)");
ok1(tal_strreg(ctx, take(tal_strdup(ctx, "HELLO WORLD!")),
take(a), &b, invalid) == false);
ok1(no_children(ctx));
tal_free(ctx);
/* Don't get fooled by \(! */
ok1(tal_strreg(ctx, "(hello) (world)!", "\\([a-z]*\\) \\([a-z]+\\)",
invalid) == true);
return exit_status();
}

48
ccan/ccan/tal/str/str/test/run-take.c

@ -1,48 +0,0 @@
#include <ccan/tal/str/str.h>
#include <ccan/tal/str/str.c>
#include <ccan/tap/tap.h>
#include "helper.h"
int main(void)
{
char *parent, *c;
plan_tests(14);
parent = tal(NULL, char);
ok1(parent);
c = tal_strdup(parent, "hello");
c = tal_strdup(parent, take(c));
ok1(strcmp(c, "hello") == 0);
ok1(tal_parent(c) == parent);
c = tal_strndup(parent, take(c), 5);
ok1(strcmp(c, "hello") == 0);
ok1(tal_parent(c) == parent);
c = tal_strndup(parent, take(c), 3);
ok1(strcmp(c, "hel") == 0);
ok1(tal_parent(c) == parent);
tal_free(c);
c = tal_strdup(parent, "hello %s");
c = tal_fmt(parent, take(c), "there");
ok1(strcmp(c, "hello there") == 0);
ok1(tal_parent(c) == parent);
/* No leftover allocations. */
tal_free(c);
ok1(no_children(parent));
tal_free(parent);
ok1(!taken_any());
/* NULL pass-through. */
c = NULL;
ok1(tal_strdup(NULL, take(c)) == NULL);
ok1(tal_strndup(NULL, take(c), 5) == NULL);
ok1(tal_fmt(NULL, take(c), 0) == NULL);
return exit_status();
}

158
ccan/ccan/tal/str/str/test/run.c

@ -1,158 +0,0 @@
#include <ccan/tal/str/str.h>
#include <stdlib.h>
#include <stdio.h>
#include <ccan/tal/str/str.c>
#include <ccan/tap/tap.h>
#include "helper.h"
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
static const char *substrings[]
= { "far", "bar", "baz", "b", "ba", "z", "ar", NULL };
int main(int argc, char *argv[])
{
char **split, *str;
void *ctx;
plan_tests(69);
split = tal_strsplit(NULL, "hello world", " ", STR_EMPTY_OK);
ok1(!strcmp(split[0], "hello"));
ok1(!strcmp(split[1], ""));
ok1(!strcmp(split[2], "world"));
ok1(split[3] == NULL);
ok1(tal_count(split) == 4);
tal_free(split);
split = tal_strsplit(NULL, "hello world", " ", STR_NO_EMPTY);
ok1(!strcmp(split[0], "hello"));
ok1(!strcmp(split[1], "world"));
ok1(split[2] == NULL);
ok1(tal_count(split) == 3);
tal_free(split);
split = tal_strsplit(NULL, " hello world", " ", STR_NO_EMPTY);
ok1(!strcmp(split[0], "hello"));
ok1(!strcmp(split[1], "world"));
ok1(split[2] == NULL);
ok1(tal_count(split) == 3);
tal_free(split);
split = tal_strsplit(NULL, "hello world", "o ", STR_EMPTY_OK);
ok1(!strcmp(split[0], "hell"));
ok1(!strcmp(split[1], ""));
ok1(!strcmp(split[2], ""));
ok1(!strcmp(split[3], "w"));
ok1(!strcmp(split[4], "rld"));
ok1(split[5] == NULL);
ok1(tal_count(split) == 6);
ctx = split;
split = tal_strsplit(ctx, "hello world", "o ", STR_EMPTY_OK);
ok1(tal_parent(split) == ctx);
tal_free(ctx);
str = tal_strjoin(NULL, (char **)substrings, ", ", STR_TRAIL);
ok1(!strcmp(str, "far, bar, baz, b, ba, z, ar, "));
ctx = str;
str = tal_strjoin(ctx, (char **)substrings, "", STR_TRAIL);
ok1(!strcmp(str, "farbarbazbbazar"));
ok1(tal_parent(str) == ctx);
str = tal_strjoin(ctx, (char **)substrings, ", ", STR_NO_TRAIL);
ok1(tal_parent(str) == ctx);
ok1(!strcmp(str, "far, bar, baz, b, ba, z, ar"));
str = tal_strjoin(ctx, (char **)substrings, "", STR_NO_TRAIL);
ok1(!strcmp(str, "farbarbazbbazar"));
ok1(tal_parent(str) == ctx);
tal_free(ctx);
ctx = tal_strdup(NULL, "context");
/* Pass through NULLs from take. */
ok1(tal_strsplit(NULL, take(NULL), " ", STR_EMPTY_OK) == NULL);
ok1(tal_strsplit(NULL, "foo", take(NULL), STR_EMPTY_OK) == NULL);
/* tal_strsplit take string. It reallocs it to same size, but
* that sometimes causes a move, so we can't directly check
* that split[0] == str. */
str = tal_strdup(ctx, "hello world");
ok1(tal_check(ctx, NULL));
ok1(tal_check(str, NULL));
split = tal_strsplit(ctx, take(str), " ", STR_EMPTY_OK);
ok1(tal_parent(split) == ctx);
ok1(!strcmp(split[0], "hello"));
ok1(!strcmp(split[1], "world"));
ok1(split[2] == NULL);
ok1(tal_check(split, NULL));
ok1(tal_check(ctx, NULL));
tal_free(split);
/* Previous free should get rid of str */
ok1(no_children(ctx));
/* tal_strsplit take delims */
str = tal_strdup(ctx, " ");
split = tal_strsplit(ctx, "hello world", take(str), STR_EMPTY_OK);
ok1(tal_parent(split) == ctx);
ok1(!strcmp(split[0], "hello"));
ok1(!strcmp(split[1], "world"));
ok1(split[2] == NULL);
ok1(tal_check(split, NULL));
ok1(tal_check(ctx, NULL));
tal_free(split);
/* str is gone... */
ok1(no_children(ctx));
/* tal_strsplit takes both. */
split = tal_strsplit(ctx, take(tal_strdup(NULL, "hello world")),
take(tal_strdup(NULL, " ")), STR_EMPTY_OK);
ok1(tal_parent(split) == ctx);
ok1(!strcmp(split[0], "hello"));
ok1(!strcmp(split[1], "world"));
ok1(split[2] == NULL);
ok1(tal_check(split, NULL));
ok1(tal_check(ctx, NULL));
tal_free(split);
/* temp allocs are gone... */
ok1(no_children(ctx));
/* tal_strjoin passthrough taken NULLs OK. */
ok1(tal_strjoin(ctx, take(NULL), "", STR_TRAIL) == NULL);
ok1(tal_strjoin(ctx, take(NULL), "", STR_NO_TRAIL) == NULL);
ok1(tal_strjoin(ctx, split, take(NULL), STR_TRAIL) == NULL);
ok1(tal_strjoin(ctx, split, take(NULL), STR_NO_TRAIL) == NULL);
/* tal_strjoin take strings[] */
split = tal_strsplit(ctx, "hello world", " ", STR_EMPTY_OK);
str = tal_strjoin(ctx, take(split), " there ", STR_NO_TRAIL);
ok1(!strcmp(str, "hello there world"));
ok1(tal_parent(str) == ctx);
/* split is gone... */
ok1(single_child(ctx, str));
tal_free(str);
ok1(no_children(ctx));
/* tal_strjoin take delim */
split = tal_strsplit(ctx, "hello world", " ", STR_EMPTY_OK);
str = tal_strjoin(ctx, split, take(tal_strdup(ctx, " there ")),
STR_NO_TRAIL);
ok1(!strcmp(str, "hello there world"));
ok1(tal_parent(str) == ctx);
tal_free(split);
/* tmp alloc is gone, str is only remainder. */
ok1(single_child(ctx, str));
tal_free(str);
ok1(no_children(ctx));
/* tal_strjoin take both. */
str = tal_strjoin(ctx, take(tal_strsplit(ctx, "hello world", " ",
STR_EMPTY_OK)),
take(tal_strdup(ctx, " there ")), STR_NO_TRAIL);
ok1(!strcmp(str, "hello there world"));
ok1(tal_parent(str) == ctx);
/* tmp allocs are gone, str is only remainder. */
ok1(single_child(ctx, str));
tal_free(str);
ok1(no_children(ctx));
tal_free(ctx);
return exit_status();
}

1
ccan/ccan/tal/talloc/talloc/LICENSE

@ -1 +0,0 @@
../../../licenses/LGPL-3

43
ccan/ccan/tal/talloc/talloc/_info

@ -1,43 +0,0 @@
#include "config.h"
#include <stdio.h>
#include <string.h>
/**
* tal/talloc - an implementation of the tal interface in terms of talloc.
*
* Tal and talloc are both hierarchical allocators, but have different APIs.
* The tal API is mostly a subset of talloc, but if your project already
* uses talloc then having both tal and talloc pointers is confusing, and
* a waste of resources.
*
* The standard convention to tell ccan modules to use this instead of
* ccan/tal is to define TAL_USE_TALLOC, usually on the commandline.
*
* Bugs:
* tal_first() and tal_next() can't be implemented.
* tal_set_backend() can only change the error function.
*
* License: LGPL
*/
int main(int argc, char *argv[])
{
if (argc != 2)
return 1;
if (strcmp(argv[1], "depends") == 0) {
printf("ccan/take\n");
printf("ccan/typesafe_cb\n");
printf("ccan/compiler\n");
printf("ccan/likely\n");
printf("ccan/str\n");
printf("talloc\n");
return 0;
}
if (strcmp(argv[1], "libs") == 0) {
printf("talloc\n");
return 0;
}
return 1;
}

263
ccan/ccan/tal/talloc/talloc/talloc.c

@ -1,263 +0,0 @@
/* Licensed under LGPL - see LICENSE file for details */
#include <ccan/tal/talloc/talloc.h>
#include <ccan/take/take.h>
#include <errno.h>
#include <assert.h>
static void (*errorfn)(const char *msg) = (void *)abort;
static void COLD call_error(const char *msg)
{
errorfn(msg);
}
static void *error_on_null(void *p, const char *msg)
{
if (!p)
call_error(msg);
return p;
}
void *tal_talloc_(const tal_t *ctx, size_t bytes, bool clear,
const char *label)
{
void *ret;
if (clear)
ret = _talloc_zero(ctx, bytes, label);
else
ret = talloc_named_const(ctx, bytes, label);
return error_on_null(ret, "allocation failure");
}
void *tal_talloc_arr_(const tal_t *ctx, size_t bytes, size_t count, bool clear,
const char *label)
{
void *ret;
if (clear)
ret = _talloc_zero_array(ctx, bytes, count, label);
else
ret = _talloc_array(ctx, bytes, count, label);
return error_on_null(ret, "array allocation failure");
}
void *tal_talloc_free_(const tal_t *ctx)
{
int saved_errno = errno;
talloc_free((void *)ctx);
errno = saved_errno;
return NULL;
}
bool tal_talloc_set_name_(tal_t *ctx, const char *name, bool literal)
{
if (!literal) {
name = talloc_strdup(ctx, name);
if (!name) {
call_error("set_name allocation failure");
return false;
}
}
talloc_set_name_const(ctx, name);
return true;
}
const char *tal_talloc_name_(const tal_t *ctx)
{
const char *p = talloc_get_name(ctx);
if (p && unlikely(strcmp(p, "UNNAMED") == 0))
p = NULL;
return p;
}
static bool adjust_size(size_t *size, size_t count)
{
/* Multiplication wrap */
if (count && unlikely(*size * count / *size != count))
goto overflow;
*size *= count;
/* Make sure we don't wrap adding header. */
if (*size + 1024 < 1024)
goto overflow;
return true;
overflow:
call_error("allocation size overflow");
return false;
}
void *tal_talloc_dup_(const tal_t *ctx, const void *p, size_t size,
size_t n, size_t extra, const char *label)
{
void *ret;
size_t nbytes = size;
if (!adjust_size(&nbytes, n)) {
if (taken(p))
tal_free(p);
return NULL;
}
/* Beware addition overflow! */
if (n + extra < n) {
call_error("dup size overflow");
if (taken(p))
tal_free(p);
return NULL;
}
if (taken(p)) {
if (unlikely(!p))
return NULL;
if (unlikely(!tal_talloc_resize_((void **)&p, size, n + extra)))
return tal_free(p);
if (unlikely(!tal_steal(ctx, p)))
return tal_free(p);
return (void *)p;
}
ret = tal_talloc_arr_(ctx, size, n + extra, false, label);
if (ret)
memcpy(ret, p, nbytes);
return ret;
}
bool tal_talloc_resize_(tal_t **ctxp, size_t size, size_t count)
{
tal_t *newp;
if (unlikely(count == 0)) {
/* Don't free it! */
newp = talloc_size(talloc_parent(*ctxp), 0);
if (!newp) {
call_error("Resize failure");
return false;
}
talloc_free(*ctxp);
*ctxp = newp;
return true;
}
/* count is unsigned, not size_t, so check for overflow here! */
if ((unsigned)count != count) {
call_error("Resize overflos");
return false;
}
newp = _talloc_realloc_array(NULL, *ctxp, size, count, NULL);
if (!newp) {
call_error("Resize failure");
return false;
}
*ctxp = newp;
return true;
}
bool tal_talloc_expand_(tal_t **ctxp, const void *src, size_t size, size_t count)
{
bool ret = false;
size_t old_count = talloc_get_size(*ctxp) / size;
/* Check for additive overflow */
if (old_count + count < count) {
call_error("dup size overflow");
goto out;
}
/* Don't point src inside thing we're expanding! */
assert(src < *ctxp
|| (char *)src >= (char *)(*ctxp) + (size * old_count));
if (!tal_talloc_resize_(ctxp, size, old_count + count))
goto out;
memcpy((char *)*ctxp + size * old_count, src, count * size);
ret = true;
out:
if (taken(src))
tal_free(src);
return ret;
}
/* Sucky inline hash table implementation, to avoid deps. */
#define HTABLE_BITS 10
struct destructor {
struct destructor *next;
const tal_t *ctx;
void (*destroy)(void *me);
};
static struct destructor *destr_hash[1 << HTABLE_BITS];
static unsigned int hash_ptr(const void *p)
{
unsigned long h = (unsigned long)p / sizeof(void *);
return (h ^ (h >> HTABLE_BITS)) & ((1 << HTABLE_BITS) - 1);
}
static int tal_talloc_destroy(const tal_t *ctx)
{
struct destructor **d = &destr_hash[hash_ptr(ctx)];
while (*d) {
if ((*d)->ctx == ctx) {
struct destructor *this = *d;
this->destroy((void *)ctx);
*d = this->next;
talloc_free(this);
}
}
return 0;
}
bool tal_talloc_add_destructor_(const tal_t *ctx, void (*destroy)(void *me))
{
struct destructor *d = talloc(ctx, struct destructor);
if (!d)
return false;
d->next = destr_hash[hash_ptr(ctx)];
d->ctx = ctx;
d->destroy = destroy;
destr_hash[hash_ptr(ctx)] = d;
talloc_set_destructor(ctx, tal_talloc_destroy);
return true;
}
bool tal_talloc_del_destructor_(const tal_t *ctx, void (*destroy)(void *me))
{
struct destructor **d = &destr_hash[hash_ptr(ctx)];
while (*d) {
if ((*d)->ctx == ctx && (*d)->destroy == destroy) {
struct destructor *this = *d;
*d = this->next;
talloc_free(this);
return true;
}
d = &(*d)->next;
}
return false;
}
void tal_talloc_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))
{
assert(!alloc_fn);
assert(!resize_fn);
assert(!free_fn);
errorfn = error_fn;
talloc_set_abort_fn(error_fn);
}
bool tal_talloc_check_(const tal_t *ctx, const char *errorstr)
{
/* We can't really check, but this iterates (and may abort). */
return !ctx || talloc_total_blocks(ctx) >= 1;
}

316
ccan/ccan/tal/talloc/talloc/talloc.h

@ -1,316 +0,0 @@
/* Licensed under LGPL - see LICENSE file for details */
#ifndef CCAN_TAL_TALLOC_H
#define CCAN_TAL_TALLOC_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 <talloc.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h>
/**
* tal_t - convenient alias for void to mark tal pointers.
*
* Since any pointer can be a tal-allocated pointer, it's often
* useful to use this typedef to mark them explicitly.
*/
typedef TALLOC_CTX tal_t;
/**
* tal - basic allocator function
* @ctx: NULL, or tal allocated object to be parent.
* @type: the type to allocate.
*
* Allocates a specific type, with a given parent context. The name
* of the object is a string of the type, but if CCAN_TAL_DEBUG is
* defined it also contains the file and line which allocated it.
*
* Example:
* int *p = tal(NULL, int);
* *p = 1;
*/
#define tal(ctx, type) \
((type *)tal_talloc_((ctx), sizeof(type), false, \
TAL_LABEL(type, "")))
/**
* talz - zeroing allocator function
* @ctx: NULL, or tal allocated object to be parent.
* @type: the type to allocate.
*
* Equivalent to tal() followed by memset() to zero.
*
* Example:
* p = talz(NULL, int);
* assert(*p == 0);
*/
#define talz(ctx, type) \
((type *)tal_talloc_((ctx), sizeof(type), true, \
TAL_LABEL(type, "")))
/**
* tal_free - free a tal-allocated pointer.
* @p: NULL, or tal allocated object to free.
*
* This calls the destructors for p (if any), then does the same for all its
* children (recursively) before finally freeing the memory. It returns
* NULL, for convenience.
*
* Note: errno is preserved by this call.
*
* Example:
* p = tal_free(p);
*/
#define tal_free(p) tal_talloc_free_(p)
/**
* tal_arr - allocate an array of objects.
* @ctx: NULL, or tal allocated object to be parent.
* @type: the type to allocate.
* @count: the number to allocate.
*
* Note that an object allocated with tal_arr() has a length property;
* see tal_count().
*
* Example:
* p = tal_arr(NULL, int, 2);
* p[0] = 0;
* p[1] = 1;
*/
#define tal_arr(ctx, type, count) \
((type *)tal_talloc_arr_((ctx), sizeof(type), (count), false, \
TAL_LABEL(type, "[]")))
/**
* tal_arrz - allocate an array of zeroed objects.
* @ctx: NULL, or tal allocated object to be parent.
* @type: the type to allocate.
* @count: the number to allocate.
*
* Note that an object allocated with tal_arrz() has a length property;
* see tal_count().
*
* Example:
* p = tal_arrz(NULL, int, 2);
* assert(p[0] == 0 && p[1] == 0);
*/
#define tal_arrz(ctx, type, count) \
((type *)tal_talloc_arr_((ctx), sizeof(type), (count), true, \
TAL_LABEL(type, "[]")))
/**
* tal_resize - enlarge or reduce a tal_arr[z].
* @p: A pointer to the tal allocated array to resize.
* @count: the number to allocate.
*
* This returns true on success (and may move *@p), or false on failure.
* If @p has a length property, it is updated on success.
*
* Example:
* tal_resize(&p, 100);
*/
#define tal_resize(p, count) \
tal_talloc_resize_((void **)(p), sizeof**(p), (count))
/**
* tal_steal - change the parent of a tal-allocated pointer.
* @ctx: The new parent.
* @ptr: The tal allocated object to move.
*
* This may need to perform an allocation, in which case it may fail; thus
* it can return NULL, otherwise returns @ptr.
*/
#define tal_steal(ctx, ptr) talloc_steal((ctx), (ptr))
/**
* tal_add_destructor - add a callback function when this context is destroyed.
* @ptr: The tal allocated object.
* @function: the function to call before it's freed.
*
* This is a more convenient form of tal_add_notifier(@ptr,
* TAL_NOTIFY_FREE, ...), in that the function prototype takes only @ptr.
*/
#define tal_add_destructor(ptr, function) \
tal_talloc_add_destructor_((ptr), typesafe_cb(void, void *, \
(function), (ptr)))
/**
* tal_del_destructor - remove a destructor callback function.
* @ptr: The tal allocated object.
* @function: the function to call before it's freed.
*
* If @function has not been successfully added as a destructor, this returns
* false.
*
* Note: you can't add more than one destructor with the talloc backend!
*/
#define tal_del_destructor(ptr, function) \
tal_talloc_del_destructor_((ptr), typesafe_cb(void, void *, \
(function), (ptr)))
/**
* tal_set_name - attach a name to a tal pointer.
* @ptr: The tal allocated object.
* @name: The name to use.
*
* The name is copied, unless we're certain it's a string literal.
*/
#define tal_set_name(ptr, name) \
tal_talloc_set_name_((ptr), (name), TAL_TALLOC_IS_LITERAL(name))
/**
* tal_name - get the name for a tal pointer.
* @ptr: The tal allocated object.
*
* Returns NULL if no name has been set.
*/
#define tal_name(ptr) \
tal_talloc_name_(ptr)
/**
* tal_count - get the count of objects in a tal_arr.
* @ptr: The tal allocated object array.
*/
#define tal_count(ptr) talloc_array_length(ptr)
/**
* tal_parent - get the parent of a tal object.
* @ctx: The tal allocated object.
*
* Returns the parent, which may be NULL. Returns NULL if @ctx is NULL.
*/
#define tal_parent(ctx) talloc_parent(ctx)
/**
* tal_dup - duplicate an object.
* @ctx: The tal allocated object to be parent of the result (may be NULL).
* @type: the type (should match type of @p!)
* @p: the object to copy (or reparented if take())
*/
#define tal_dup(ctx, type, p) \
((type *)tal_talloc_dup_((ctx), tal_talloc_typechk_(p, type *), \
sizeof(type), 1, 0, \
TAL_LABEL(type, "")))
/**
* tal_dup_arr - duplicate an array.
* @ctx: The tal allocated object to be parent of the result (may be NULL).
* @type: the type (should match type of @p!)
* @p: the array to copy (or resized & reparented if take())
* @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) \
((type *)tal_talloc_dup_((ctx), tal_talloc_typechk_(p, type *), \
sizeof(type), (n), (extra), \
TAL_LABEL(type, "[]")))
/**
* tal_set_backend - set the allocation or error functions to use
* @alloc_fn: NULL
* @resize_fn: NULL
* @free_fn: NULL
* @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
* called if malloc or realloc fail.
*/
#define tal_set_backend(alloc_fn, resize_fn, free_fn, error_fn) \
tal_talloc_set_backend_((alloc_fn), (resize_fn), (free_fn), (error_fn))
/**
* tal_expand - expand a tal array with contents.
* @a1p: a pointer to the tal array to expand.
* @a2: the second array (can be take()).
* @num2: the number of elements in the second array.
*
* Note that *@a1 and @a2 should be the same type. tal_count(@a1) will
* be increased by @num2.
*
* Example:
* 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);
*/
#define tal_expand(a1p, a2, num2) \
tal_talloc_expand_((void **)(a1p), (a2), sizeof**(a1p), \
(num2) + 0*sizeof(*(a1p) == (a2)))
/**
* tal_check - set the allocation or error functions to use
* @ctx: a tal context, or NULL.
* @errorstr: a string to prepend calls to error_fn, or NULL.
*
* This sanity-checks a tal tree (unless NDEBUG is defined, in which case
* it simply returns true). If errorstr is not null, error_fn is called
* when a problem is found, otherwise it is not.
*/
#define tal_check(ctx, errorstr) \
tal_talloc_check_((ctx), (errorstr))
/* Internal support functions */
#ifndef TAL_TALLOC_LABEL
#ifdef CCAN_TAL_NO_LABELS
#define TAL_LABEL(type, arr) NULL
#else
#ifdef CCAN_TAL_DEBUG
#define TAL_LABEL(type, arr) \
__FILE__ ":" stringify(__LINE__) ":" stringify(type) arr
#else
#define TAL_LABEL(type, arr) stringify(type) arr
#endif /* CCAN_TAL_DEBUG */
#endif
#endif
#if HAVE_BUILTIN_CONSTANT_P
#define TAL_TALLOC_IS_LITERAL(str) __builtin_constant_p(str)
#else
#define TAL_TALLOC_IS_LITERAL(str) false
#endif
#if HAVE_TYPEOF && HAVE_STATEMENT_EXPR
/* Careful: ptr can be const foo *, ptype is foo *. Also, ptr could
* be an array, eg "hello". */
#define tal_talloc_typechk_(ptr, ptype) ({ __typeof__((ptr)+0) _p = (ptype)(ptr); _p; })
#else
#define tal_talloc_typechk_(ptr, ptype) (ptr)
#endif
void *tal_talloc_(const tal_t *ctx, size_t bytes, bool clear,
const char *label);
void *tal_talloc_arr_(const tal_t *ctx, size_t bytes, size_t count, bool clear,
const char *label);
void *tal_talloc_free_(const tal_t *ctx);
const char *tal_talloc_name_(const tal_t *ctx);
bool tal_talloc_set_name_(tal_t *ctx, const char *name, bool literal);
bool tal_talloc_add_destructor_(const tal_t *ctx, void (*destroy)(void *me));
bool tal_talloc_del_destructor_(const tal_t *ctx, void (*destroy)(void *me));
/* ccan/tal/str uses this, so define it. */
#define tal_dup_(ctx, p, size, n, extra, add_count, label) \
tal_talloc_dup_((ctx), (p), (size), (n), (extra), (label))
void *tal_talloc_dup_(const tal_t *ctx, const void *p, size_t size,
size_t n, size_t extra, const char *label);
bool tal_talloc_resize_(tal_t **ctxp, size_t size, size_t count);
bool tal_talloc_expand_(tal_t **ctxp, const void *src, size_t size, size_t count);
bool tal_talloc_check_(const tal_t *ctx, const char *errorstr);
void tal_talloc_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));
#endif /* CCAN_TAL_TALLOC_H */

46
ccan/ccan/tal/talloc/talloc/test/run-array.c

@ -1,46 +0,0 @@
#include <ccan/tal/talloc/talloc.h>
#include <ccan/tal/talloc/talloc.c>
#include <ccan/tap/tap.h>
int main(void)
{
char *parent, *c[4];
int i;
plan_tests(11);
parent = tal(NULL, char);
ok1(parent);
/* Zeroing allocations. */
for (i = 0; i < 4; i++) {
c[i] = talz(parent, char);
ok1(*c[i] == '\0');
tal_free(c[i]);
}
/* Array allocation. */
for (i = 0; i < 4; i++) {
c[i] = tal_arr(parent, char, 4);
strcpy(c[i], "abc");
tal_free(c[i]);
}
/* Zeroing array allocation. */
for (i = 0; i < 4; i++) {
c[i] = tal_arrz(parent, char, 4);
ok1(!c[i][0] && !c[i][1] && !c[i][2] && !c[i][3]);
strcpy(c[i], "abc");
tal_free(c[i]);
}
/* Resizing. */
c[0] = tal_arrz(parent, char, 4);
ok1(tal_resize(&c[0], 6));
strcpy(c[0], "hello");
tal_free(c[0]);
ok1(talloc_total_blocks(parent) == 1);
tal_free(parent);
return exit_status();
}

33
ccan/ccan/tal/talloc/talloc/test/run-count.c

@ -1,33 +0,0 @@
#include <ccan/tal/talloc/talloc.h>
#include <ccan/tal/talloc/talloc.c>
#include <ccan/tap/tap.h>
int main(void)
{
char *p1, *p2;
plan_tests(12);
p1 = tal(NULL, char);
ok1(p1);
ok1(tal_count(p1) == 1);
p2 = tal_arr(p1, char, 1);
ok1(p2);
ok1(tal_count(p2) == 1);
ok1(tal_resize(&p2, 2));
ok1(tal_count(p2) == 2);
ok1(tal_check(NULL, NULL));
tal_free(p2);
p2 = tal_arrz(p1, char, 7);
ok1(p2);
ok1(tal_count(p2) == 7);
ok1(tal_resize(&p2, 0));
ok1(tal_count(p2) == 0);
ok1(tal_check(NULL, NULL));
tal_free(p2);
tal_free(p1);
return exit_status();
}

67
ccan/ccan/tal/talloc/talloc/test/run-destructor.c

@ -1,67 +0,0 @@
#include <ccan/tal/talloc/talloc.h>
#include <ccan/tal/talloc/talloc.c>
#include <ccan/tap/tap.h>
static char *parent, *child;
static int destroy_count;
/* Parent gets destroyed first. */
static void destroy_parent(char *p)
{
ok1(p == parent);
ok1(destroy_count == 0);
/* Can still access child. */
*child = '1';
destroy_count++;
}
static void destroy_child(char *p)
{
ok1(p == child);
ok1(destroy_count == 1);
/* Can still access parent (though destructor has been called). */
*parent = '1';
destroy_count++;
}
static void destroy_inc(char *p)
{
destroy_count++;
}
int main(void)
{
char *child2;
plan_tests(18);
destroy_count = 0;
parent = tal(NULL, char);
child = tal(parent, char);
ok1(tal_add_destructor(parent, destroy_parent));
ok1(tal_add_destructor(child, destroy_child));
tal_free(parent);
ok1(destroy_count == 2);
destroy_count = 0;
parent = tal(NULL, char);
child = tal(parent, char);
ok1(tal_add_destructor(parent, destroy_parent));
ok1(tal_add_destructor(child, destroy_child));
ok1(tal_del_destructor(child, destroy_child));
tal_free(parent);
ok1(destroy_count == 1);
destroy_count = 0;
parent = tal(NULL, char);
child = tal(parent, char);
child2 = tal(parent, char);
ok1(tal_add_destructor(parent, destroy_inc));
ok1(tal_add_destructor(parent, destroy_inc));
ok1(tal_add_destructor(child, destroy_inc));
ok1(tal_add_destructor(child2, destroy_inc));
tal_free(parent);
ok1(destroy_count == 4);
return exit_status();
}

35
ccan/ccan/tal/talloc/talloc/test/run-expand.c

@ -1,35 +0,0 @@
#include <ccan/tal/talloc/talloc.h>
#include <ccan/tal/talloc/talloc.c>
#include <ccan/tap/tap.h>
int main(void)
{
int *a;
const int arr[] = { 1, 2 };
plan_tests(14);
talloc_enable_null_tracking_no_autofree();
a = tal_arrz(NULL, int, 1);
ok1(a);
ok1(tal_expand(&a, arr, 2));
ok1(tal_count(a) == 3);
ok1(a[0] == 0);
ok1(a[1] == 1);
ok1(a[2] == 2);
ok1(tal_expand(&a, take(tal_arrz(NULL, int, 1)), 1));
ok1(tal_count(a) == 4);
ok1(a[0] == 0);
ok1(a[1] == 1);
ok1(a[2] == 2);
ok1(a[3] == 0);
ok1(talloc_total_blocks(NULL) == 2);
ok1(talloc_total_blocks(a) == 1);
tal_free(a);
talloc_disable_null_tracking();
return exit_status();
}

26
ccan/ccan/tal/talloc/talloc/test/run-free.c

@ -1,26 +0,0 @@
#include <ccan/tal/talloc/talloc.h>
#include <ccan/tal/talloc/talloc.c>
#include <ccan/tap/tap.h>
#include <errno.h>
static void destroy_errno(char *p)
{
errno = ENOENT;
}
int main(void)
{
char *p;
plan_tests(2);
p = tal(NULL, char);
ok1(tal_add_destructor(p, destroy_errno));
/* Errno save/restored across free. */
errno = EINVAL;
tal_free(p);
ok1(errno == EINVAL);
return exit_status();
}

34
ccan/ccan/tal/talloc/talloc/test/run-named-debug.c

@ -1,34 +0,0 @@
#define CCAN_TAL_DEBUG
#include <ccan/tal/talloc/talloc.h>
#include <ccan/tal/talloc/talloc.c>
#include <ccan/tap/tap.h>
int main(void)
{
int *p;
char name[] = "test name";
plan_tests(6);
p = tal(NULL, int);
ok1(strcmp(tal_name(p), __FILE__ ":13:int") == 0);
tal_set_name(p, "some literal");
ok1(strcmp(tal_name(p), "some literal") == 0);
tal_set_name(p, name);
ok1(strcmp(tal_name(p), name) == 0);
/* You can't reuse my pointer though! */
ok1(tal_name(p) != name);
tal_set_name(p, "some other literal");
ok1(strcmp(tal_name(p), "some other literal") == 0);
tal_free(p);
p = tal_arr(NULL, int, 2);
ok1(strcmp(tal_name(p), __FILE__ ":29:int[]") == 0);
tal_free(p);
return exit_status();
}

30
ccan/ccan/tal/talloc/talloc/test/run-named-nolabels.c

@ -1,30 +0,0 @@
#define CCAN_TAL_NO_LABELS
#include <ccan/tal/talloc/talloc.h>
#include <ccan/tal/talloc/talloc.c>
#include <ccan/tap/tap.h>
int main(void)
{
int *p;
char name[] = "test name";
plan_tests(5);
p = tal(NULL, int);
ok1(tal_name(p) == NULL);
tal_set_name(p, "some literal");
ok1(strcmp(tal_name(p), "some literal") == 0);
tal_set_name(p, name);
ok1(strcmp(tal_name(p), name) == 0);
/* You can't reuse my pointer though! */
ok1(tal_name(p) != name);
tal_set_name(p, "some other literal");
ok1(strcmp(tal_name(p), "some other literal") == 0);
tal_free(p);
return exit_status();
}

33
ccan/ccan/tal/talloc/talloc/test/run-named.c

@ -1,33 +0,0 @@
#include <ccan/tal/talloc/talloc.h>
#include <ccan/tal/talloc/talloc.c>
#include <ccan/tap/tap.h>
int main(void)
{
int *p;
char name[] = "test name";
plan_tests(6);
p = tal(NULL, int);
ok1(strcmp(tal_name(p), "int") == 0);
tal_set_name(p, "some literal");
ok1(strcmp(tal_name(p), "some literal") == 0);
tal_set_name(p, name);
ok1(strcmp(tal_name(p), name) == 0);
/* You can't reuse my pointer though! */
ok1(tal_name(p) != name);
tal_set_name(p, "some other literal");
ok1(strcmp(tal_name(p), "some other literal") == 0);
tal_free(p);
p = tal_arr(NULL, int, 2);
ok1(strcmp(tal_name(p), "int[]") == 0);
tal_free(p);
return exit_status();
}

100
ccan/ccan/tal/talloc/talloc/test/run-overflow.c

@ -1,100 +0,0 @@
#include <ccan/tal/talloc/talloc.h>
#include <ccan/tal/talloc/talloc.c>
#include <ccan/tap/tap.h>
static int error_count;
static void my_error(const char *msg)
{
error_count++;
}
int main(void)
{
void *p;
int *pi, *origpi;
char *cp;
plan_tests(30);
tal_set_backend(NULL, NULL, NULL, my_error);
talloc_enable_null_tracking_no_autofree();
p = tal_arr(NULL, int, (size_t)-1);
ok1(!p);
ok1(error_count == 1);
p = tal_arr(NULL, char, (size_t)-2);
ok1(!p);
ok1(error_count == 2);
/* Now try overflow cases for tal_dup. */
error_count = 0;
origpi = tal_arr(NULL, int, 100);
ok1(origpi);
ok1(error_count == 0);
pi = tal_dup_arr(NULL, int, origpi, (size_t)-1, 0);
ok1(!pi);
ok1(error_count == 1);
pi = tal_dup_arr(NULL, int, origpi, 0, (size_t)-1);
ok1(!pi);
ok1(error_count == 2);
pi = tal_dup_arr(NULL, int, origpi, (size_t)-1UL / sizeof(int),
(size_t)-1UL / sizeof(int));
ok1(!pi);
ok1(error_count == 3);
/* This will still overflow when tal_hdr is added. */
pi = tal_dup_arr(NULL, int, origpi, (size_t)-1UL / sizeof(int) / 2,
(size_t)-1UL / sizeof(int) / 2);
ok1(!pi);
ok1(error_count == 4);
ok1(talloc_total_blocks(NULL) == 2);
tal_free(origpi);
/* Now, check that with taltk() we free old one on failure. */
origpi = tal_arr(NULL, int, 100);
error_count = 0;
pi = tal_dup_arr(NULL, int, take(origpi), (size_t)-1, 0);
ok1(!pi);
ok1(error_count == 1);
origpi = tal_arr(NULL, int, 100);
error_count = 0;
pi = tal_dup_arr(NULL, int, take(origpi), 0, (size_t)-1);
ok1(!pi);
ok1(error_count == 1);
ok1(talloc_total_blocks(NULL) == 1);
origpi = tal_arr(NULL, int, 100);
error_count = 0;
pi = tal_dup_arr(NULL, int, take(origpi), (size_t)-1UL / sizeof(int),
(size_t)-1UL / sizeof(int));
ok1(!pi);
ok1(error_count == 1);
ok1(talloc_total_blocks(NULL) == 1);
origpi = tal_arr(NULL, int, 100);
error_count = 0;
/* This will still overflow when tal_hdr is added. */
pi = tal_dup_arr(NULL, int, take(origpi), (size_t)-1UL / sizeof(int) / 2,
(size_t)-1UL / sizeof(int) / 2);
ok1(!pi);
ok1(error_count == 1);
ok1(talloc_total_blocks(NULL) == 1);
/* Overflow on expand addition. */
cp = tal_arr(p, char, 100);
ok1(!tal_expand(&cp, NULL, (size_t)-99UL));
ok1(error_count == 2);
tal_free(cp);
/* Overflow when multiplied by size */
origpi = tal_arr(NULL, int, 100);
ok1(!tal_expand(&origpi, NULL, (size_t)-1UL / sizeof(int)));
ok1(error_count == 3);
tal_free(origpi);
talloc_disable_null_tracking();
return exit_status();
}

40
ccan/ccan/tal/talloc/talloc/test/run-steal.c

@ -1,40 +0,0 @@
#include <ccan/tal/talloc/talloc.h>
#include <ccan/tal/talloc/talloc.c>
#include <ccan/tap/tap.h>
int main(void)
{
char *p[5];
unsigned int i;
plan_tests(9);
p[0] = tal(NULL, char);
for (i = 1; i < 5; i++)
p[i] = tal(p[i-1], char);
tal_check(NULL, "check");
/* Steal node with no children. */
ok1(tal_steal(p[0], p[4]) == p[4]);
tal_check(NULL, "check");
/* Noop steal. */
ok1(tal_steal(p[0], p[4]) == p[4]);
tal_check(NULL, "check");
/* Steal with children. */
ok1(tal_steal(p[0], p[1]) == p[1]);
tal_check(NULL, "check");
/* Noop steal. */
ok1(tal_steal(p[0], p[1]) == p[1]);
tal_check(NULL, "check");
/* Steal from direct child. */
ok1(tal_steal(p[0], p[2]) == p[2]);
tal_check(NULL, "check");
ok1(tal_parent(p[1]) == p[0]);
ok1(tal_parent(p[2]) == p[0]);
ok1(tal_parent(p[3]) == p[2]);
ok1(tal_parent(p[4]) == p[0]);
tal_free(p[0]);
return exit_status();
}

56
ccan/ccan/tal/talloc/talloc/test/run-take.c

@ -1,56 +0,0 @@
#include <ccan/tal/talloc/talloc.h>
#include <ccan/tal/talloc/talloc.c>
#include <ccan/tap/tap.h>
int main(void)
{
char *parent, *c;
plan_tests(21);
/* We can take NULL. */
ok1(take(NULL) == NULL);
ok1(is_taken(NULL));
ok1(taken(NULL)); /* Undoes take() */
ok1(!is_taken(NULL));
ok1(!taken(NULL));
parent = tal(NULL, char);
ok1(parent);
ok1(take(parent) == parent);
ok1(is_taken(parent));
ok1(taken(parent)); /* Undoes take() */
ok1(!is_taken(parent));
ok1(!taken(parent));
c = tal(parent, char);
*c = 'h';
c = tal_dup(parent, char, take(c));
ok1(c[0] == 'h');
ok1(tal_parent(c) == parent);
c = tal_dup_arr(parent, char, take(c), 1, 2);
ok1(c[0] == 'h');
strcpy(c, "hi");
ok1(tal_parent(c) == parent);
/* dup must reparent child. */
c = tal_dup(NULL, char, take(c));
ok1(c[0] == 'h');
ok1(tal_parent(c) == NULL);
/* No leftover allocations. */
tal_free(c);
ok1(talloc_total_blocks(parent) == 1);
tal_free(parent);
ok1(!taken_any());
/* NULL pass-through. */
c = NULL;
ok1(tal_dup_arr(NULL, char, take(c), 5, 5) == NULL);
ok1(!taken_any());
return exit_status();
}

44
ccan/ccan/tal/talloc/talloc/test/run.c

@ -1,44 +0,0 @@
#include <ccan/tal/talloc/talloc.h>
#include <ccan/tal/talloc/talloc.c>
#include <ccan/tap/tap.h>
int main(void)
{
char *parent, *c[4];
int i, j;
plan_tests(9);
/* tal_free(NULL) works. */
ok1(tal_free(NULL) == NULL);
parent = tal(NULL, char);
ok1(parent);
ok1(tal_parent(parent) == NULL);
ok1(tal_parent(NULL) == NULL);
for (i = 0; i < 4; i++)
c[i] = tal(parent, char);
for (i = 0; i < 4; i++)
ok1(tal_parent(c[i]) == parent);
/* Free parent. */
ok1(tal_free(parent) == NULL);
parent = tal(NULL, char);
/* Test freeing in every order */
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++)
c[j] = tal(parent, char);
tal_free(c[i]);
tal_free(c[(i+1) % 4]);
tal_free(c[(i+2) % 4]);
tal_free(c[(i+3) % 4]);
}
tal_free(parent);
return exit_status();
}
Loading…
Cancel
Save