Commit bb480e55 authored by Rusty Russell's avatar Rusty Russell

tal: take implies NULL passthrough.

This makes error handling much more convenient, since take is usually
used for chaining functions.
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent e03d7ecb
...@@ -718,18 +718,26 @@ bool tal_resize_(tal_t **ctxp, size_t size) ...@@ -718,18 +718,26 @@ bool tal_resize_(tal_t **ctxp, size_t size)
char *tal_strdup(const tal_t *ctx, const char *p) char *tal_strdup(const tal_t *ctx, const char *p)
{ {
return tal_dup(ctx, char, p, strlen(p)+1, 0); /* We have to let through NULL for take(). */
return tal_dup(ctx, char, p, p ? strlen(p) + 1: 1, 0);
} }
char *tal_strndup(const tal_t *ctx, const char *p, size_t n) char *tal_strndup(const tal_t *ctx, const char *p, size_t n)
{ {
size_t len;
char *ret; char *ret;
if (strlen(p) < n) /* We have to let through NULL for take(). */
n = strlen(p); if (likely(p)) {
ret = tal_dup(ctx, char, p, n, 1); len = strlen(p);
if (len > n)
len = n;
} else
len = n;
ret = tal_dup(ctx, char, p, len, 1);
if (ret) if (ret)
ret[n] = '\0'; ret[len] = '\0';
return ret; return ret;
} }
...@@ -779,10 +787,15 @@ char *tal_asprintf(const tal_t *ctx, const char *fmt, ...) ...@@ -779,10 +787,15 @@ char *tal_asprintf(const tal_t *ctx, const char *fmt, ...)
char *tal_vasprintf(const tal_t *ctx, const char *fmt, va_list ap) char *tal_vasprintf(const tal_t *ctx, const char *fmt, va_list ap)
{ {
size_t max = strlen(fmt) * 2; size_t max;
char *buf; char *buf;
int ret; int ret;
if (!fmt && taken(fmt))
return NULL;
/* A decent guess to start. */
max = strlen(fmt) * 2;
buf = tal_arr(ctx, char, max); buf = tal_arr(ctx, char, max);
while (buf) { while (buf) {
va_list ap2; va_list ap2;
......
...@@ -304,7 +304,7 @@ static inline size_t tal_sizeof_(size_t size, size_t count) ...@@ -304,7 +304,7 @@ static inline size_t tal_sizeof_(size_t size, size_t count)
#if HAVE_STATEMENT_EXPR #if HAVE_STATEMENT_EXPR
/* Careful: ptr can be const foo *, ptype is foo *. Also, ptr could /* Careful: ptr can be const foo *, ptype is foo *. Also, ptr could
* be an array, eg "hello". */ * be an array, eg "hello". */
#define tal_typechk_(ptr, ptype) ({ __typeof__(&*(ptr)) _p = (ptype)(ptr); _p; }) #define tal_typechk_(ptr, ptype) ({ __typeof__((ptr)+0) _p = (ptype)(ptr); _p; })
#else #else
#define tal_typechk_(ptr, ptype) (ptr) #define tal_typechk_(ptr, ptype) (ptr)
#endif #endif
......
...@@ -6,18 +6,22 @@ int main(void) ...@@ -6,18 +6,22 @@ int main(void)
{ {
char *parent, *c; char *parent, *c;
plan_tests(24); plan_tests(32);
/* We can take NULL. */ /* We can take NULL. */
ok1(take(NULL) == NULL); ok1(take(NULL) == NULL);
ok1(is_taken(NULL));
ok1(taken(NULL)); /* Undoes take() */ ok1(taken(NULL)); /* Undoes take() */
ok1(!is_taken(NULL));
ok1(!taken(NULL)); ok1(!taken(NULL));
parent = tal(NULL, char); parent = tal(NULL, char);
ok1(parent); ok1(parent);
ok1(take(parent) == parent); ok1(take(parent) == parent);
ok1(is_taken(parent));
ok1(taken(parent)); /* Undoes take() */ ok1(taken(parent)); /* Undoes take() */
ok1(!is_taken(parent));
ok1(!taken(parent)); ok1(!taken(parent));
c = tal_strdup(parent, "hello"); c = tal_strdup(parent, "hello");
...@@ -63,5 +67,12 @@ int main(void) ...@@ -63,5 +67,12 @@ int main(void)
tal_free(parent); tal_free(parent);
ok1(!taken_any()); 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_dup(NULL, char, take(c), 5, 5) == NULL);
ok1(tal_asprintf(NULL, take(c), 0) == NULL);
return exit_status(); return exit_status();
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment