Commit e81b5273 authored by Rusty Russell's avatar Rusty Russell

tal: make tal_next() only return immediate children.

I tried to use it and got this wrong: moreover, I wanted to control
topology, which requires nested iteration, and skip children
of a node which I knew was changing.
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent 5e37a0fe
...@@ -47,7 +47,7 @@ int main(void) ...@@ -47,7 +47,7 @@ int main(void)
path = path_basename(ctx, take(tal_strdup(ctx, ".."))); path = path_basename(ctx, take(tal_strdup(ctx, "..")));
ok1(streq(path, "..")); ok1(streq(path, ".."));
ok1(tal_parent(path) == ctx); ok1(tal_parent(path) == ctx);
ok1(tal_first(ctx) == path && !tal_next(ctx, path)); ok1(tal_first(ctx) == path && !tal_next(path));
tal_free(path); tal_free(path);
ok1(path_basename(ctx, take(NULL)) == NULL); ok1(path_basename(ctx, take(NULL)) == NULL);
ok1(!tal_first(ctx)); ok1(!tal_first(ctx));
......
...@@ -36,7 +36,7 @@ int main(void) ...@@ -36,7 +36,7 @@ int main(void)
ok1(strstarts(path, cwd)); ok1(strstarts(path, cwd));
ok1(path[strlen(cwd)] == PATH_SEP); ok1(path[strlen(cwd)] == PATH_SEP);
ok1(strlen(path) == strlen(cwd) + 1 + strlen("run-canon-foo")); ok1(strlen(path) == strlen(cwd) + 1 + strlen("run-canon-foo"));
ok1(tal_first(ctx) == path && tal_next(ctx, path) == NULL); ok1(tal_first(ctx) == path && tal_next(path) == NULL);
path2 = path_canon(ctx, "run-canon-link"); path2 = path_canon(ctx, "run-canon-link");
ok1(streq(path2, path)); ok1(streq(path2, path));
......
...@@ -47,7 +47,7 @@ int main(void) ...@@ -47,7 +47,7 @@ int main(void)
path = path_dirname(ctx, take(tal_strdup(ctx, ".."))); path = path_dirname(ctx, take(tal_strdup(ctx, "..")));
ok1(streq(path, ".")); ok1(streq(path, "."));
ok1(tal_parent(path) == ctx); ok1(tal_parent(path) == ctx);
ok1(tal_first(ctx) == path && !tal_next(ctx, path)); ok1(tal_first(ctx) == path && !tal_next(path));
tal_free(path); tal_free(path);
ok1(path_dirname(ctx, take(NULL)) == NULL); ok1(path_dirname(ctx, take(NULL)) == NULL);
ok1(!tal_first(ctx)); ok1(!tal_first(ctx));
......
...@@ -32,39 +32,39 @@ int main(void) ...@@ -32,39 +32,39 @@ int main(void)
path = path_join(ctx, "foo", take(tal_strdup(ctx, "bar"))); path = path_join(ctx, "foo", take(tal_strdup(ctx, "bar")));
ok1(streq(path, "foo/bar")); ok1(streq(path, "foo/bar"));
ok1(tal_parent(path) == ctx); ok1(tal_parent(path) == ctx);
ok1(tal_first(ctx) == path && tal_next(ctx, path) == NULL); ok1(tal_first(ctx) == path && tal_next(path) == NULL && tal_first(path) == NULL);
tal_free(path); tal_free(path);
path = path_join(ctx, "foo", take(tal_strdup(ctx, "/bar"))); path = path_join(ctx, "foo", take(tal_strdup(ctx, "/bar")));
ok1(streq(path, "/bar")); ok1(streq(path, "/bar"));
ok1(tal_parent(path) == ctx); ok1(tal_parent(path) == ctx);
ok1(tal_first(ctx) == path && tal_next(ctx, path) == NULL); ok1(tal_first(ctx) == path && tal_next(path) == NULL && tal_first(path) == NULL);
tal_free(path); tal_free(path);
path = path_join(ctx, take(tal_strdup(ctx, "foo")), "bar"); path = path_join(ctx, take(tal_strdup(ctx, "foo")), "bar");
ok1(streq(path, "foo/bar")); ok1(streq(path, "foo/bar"));
ok1(tal_parent(path) == ctx); ok1(tal_parent(path) == ctx);
ok1(tal_first(ctx) == path && tal_next(ctx, path) == NULL); ok1(tal_first(ctx) == path && tal_next(path) == NULL && tal_first(path) == NULL);
tal_free(path); tal_free(path);
path = path_join(ctx, take(tal_strdup(ctx, "foo")), "/bar"); path = path_join(ctx, take(tal_strdup(ctx, "foo")), "/bar");
ok1(streq(path, "/bar")); ok1(streq(path, "/bar"));
ok1(tal_parent(path) == ctx); ok1(tal_parent(path) == ctx);
ok1(tal_first(ctx) == path && tal_next(ctx, path) == NULL); ok1(tal_first(ctx) == path && tal_next(path) == NULL && tal_first(path) == NULL);
tal_free(path); tal_free(path);
path = path_join(ctx, take(tal_strdup(ctx, "foo")), path = path_join(ctx, take(tal_strdup(ctx, "foo")),
take(tal_strdup(ctx, "bar"))); take(tal_strdup(ctx, "bar")));
ok1(streq(path, "foo/bar")); ok1(streq(path, "foo/bar"));
ok1(tal_parent(path) == ctx); ok1(tal_parent(path) == ctx);
ok1(tal_first(ctx) == path && tal_next(ctx, path) == NULL); ok1(tal_first(ctx) == path && tal_next(path) == NULL && tal_first(path) == NULL);
tal_free(path); tal_free(path);
path = path_join(ctx, take(tal_strdup(ctx, "foo")), path = path_join(ctx, take(tal_strdup(ctx, "foo")),
take(tal_strdup(ctx, "/bar"))); take(tal_strdup(ctx, "/bar")));
ok1(streq(path, "/bar")); ok1(streq(path, "/bar"));
ok1(tal_parent(path) == ctx); ok1(tal_parent(path) == ctx);
ok1(tal_first(ctx) == path && tal_next(ctx, path) == NULL); ok1(tal_first(ctx) == path && tal_next(path) == NULL && tal_first(path) == NULL);
tal_free(path); tal_free(path);
path = path_join(ctx, take(NULL), "bar"); path = path_join(ctx, take(NULL), "bar");
......
...@@ -30,7 +30,7 @@ int main(void) ...@@ -30,7 +30,7 @@ int main(void)
link = path_readlink(ctx, take(tal_strdup(ctx, "run-readlink-link"))); link = path_readlink(ctx, take(tal_strdup(ctx, "run-readlink-link")));
ok1(tal_parent(link) == ctx); ok1(tal_parent(link) == ctx);
ok1(streq(link, "/tmp")); ok1(streq(link, "/tmp"));
ok1(tal_first(ctx) == link && tal_next(ctx, link) == NULL); ok1(tal_first(ctx) == link && tal_next(link) == NULL && tal_first(link) == NULL);
unlink("run-readlink-link"); unlink("run-readlink-link");
......
...@@ -98,7 +98,7 @@ int main(void) ...@@ -98,7 +98,7 @@ int main(void)
ok1(!split); ok1(!split);
ok1(tal_first(ctx) == NULL); ok1(tal_first(ctx) == NULL);
ok1(tal_first(NULL) == ctx && tal_next(NULL, ctx) == NULL); ok1(tal_first(NULL) == ctx && tal_next(ctx) == NULL && tal_first(ctx) == NULL);
tal_free(ctx); tal_free(ctx);
return exit_status(); return exit_status();
......
...@@ -17,6 +17,6 @@ static inline bool no_children(const void *ctx) ...@@ -17,6 +17,6 @@ static inline bool no_children(const void *ctx)
static inline bool single_child(const void *ctx, const void *child) static inline bool single_child(const void *ctx, const void *child)
{ {
return tal_first(ctx) == child && !tal_next(ctx, child); return tal_first(ctx) == child && !tal_next(child) && !tal_first(child);
} }
#endif #endif
...@@ -630,31 +630,16 @@ tal_t *tal_first(const tal_t *root) ...@@ -630,31 +630,16 @@ tal_t *tal_first(const tal_t *root)
return from_tal_hdr(c); return from_tal_hdr(c);
} }
tal_t *tal_next(const tal_t *root, const tal_t *prev) tal_t *tal_next(const tal_t *prev)
{ {
struct tal_hdr *c, *t = debug_tal(to_tal_hdr(prev)), *top; struct tal_hdr *next, *prevhdr = debug_tal(to_tal_hdr(prev));
struct list_head *head;
/* Children? */
c = first_child(t);
if (c)
return from_tal_hdr(c);
top = to_tal_hdr_or_null(root);
do {
struct tal_hdr *next;
struct list_node *end;
end = &ignore_destroying_bit(t->parent_child)->children.n;
next = list_entry(t->list.next, struct tal_hdr, list);
if (&next->list != end)
return from_tal_hdr(next);
/* OK, go back to parent. */
t = ignore_destroying_bit(t->parent_child)->parent;
} while (t != top);
head = &ignore_destroying_bit(prevhdr->parent_child)->children;
next = list_next(head, prevhdr, list);
if (!next)
return NULL; return NULL;
return from_tal_hdr(next);
} }
tal_t *tal_parent(const tal_t *ctx) tal_t *tal_parent(const tal_t *ctx)
......
...@@ -262,7 +262,7 @@ const char *tal_name(const tal_t *ptr); ...@@ -262,7 +262,7 @@ const char *tal_name(const tal_t *ptr);
size_t tal_count(const tal_t *ptr); size_t tal_count(const tal_t *ptr);
/** /**
* tal_first - get the first tal object child. * tal_first - get the first immediate tal object child.
* @root: The tal allocated object to start with, or NULL. * @root: The tal allocated object to start with, or NULL.
* *
* Returns NULL if there are no children. * Returns NULL if there are no children.
...@@ -270,15 +270,13 @@ size_t tal_count(const tal_t *ptr); ...@@ -270,15 +270,13 @@ size_t tal_count(const tal_t *ptr);
tal_t *tal_first(const tal_t *root); tal_t *tal_first(const tal_t *root);
/** /**
* tal_next - get the next tal object child. * tal_next - get the next immediate tal object child.
* @root: The tal allocated object to start with, or NULL.
* @prev: The return value from tal_first or tal_next. * @prev: The return value from tal_first or tal_next.
* *
* Returns NULL if there are no more children. This should be safe to * Returns NULL if there are no more immediate children. This should be safe to
* call on an altering tree unless @prev is no longer a descendent of * call on an altering tree unless @prev is no longer valid.
* @root.
*/ */
tal_t *tal_next(const tal_t *root, const tal_t *prev); tal_t *tal_next(const const tal_t *prev);
/** /**
* tal_parent - get the parent of a tal object. * tal_parent - get the parent of a tal object.
......
...@@ -24,7 +24,7 @@ int main(void) ...@@ -24,7 +24,7 @@ int main(void)
ok1(a[1] == 1); ok1(a[1] == 1);
ok1(a[2] == 2); ok1(a[2] == 2);
ok1(a[3] == 0); ok1(a[3] == 0);
ok1(tal_first(NULL) == a && !tal_next(NULL, a)); ok1(tal_first(NULL) == a && !tal_next(a) && !tal_first(a));
tal_free(a); tal_free(a);
......
...@@ -4,9 +4,33 @@ ...@@ -4,9 +4,33 @@
#define NUM 1000 #define NUM 1000
static int set_children(const tal_t *parent, char val)
{
char *iter;
int num = 0;
for (iter = tal_first(parent); iter; iter = tal_next(iter)) {
ok1(*iter == '0');
*iter = val;
num++;
num += set_children(iter, val);
}
return num;
}
static void check_children(const tal_t *parent, char val)
{
const char *iter;
for (iter = tal_first(parent); iter; iter = tal_next(iter)) {
ok1(*iter == val);
check_children(iter, val);
}
}
int main(void) int main(void)
{ {
char *p[NUM] = { NULL }, *iter; char *p[NUM] = { NULL };
int i; int i;
plan_tests(NUM + 1 + NUM); plan_tests(NUM + 1 + NUM);
...@@ -17,18 +41,13 @@ int main(void) ...@@ -17,18 +41,13 @@ int main(void)
*p[i] = '0'; *p[i] = '0';
} }
i = 0; i = set_children(NULL, '1');
for (iter = tal_first(NULL); iter; iter = tal_next(NULL, iter)) {
i++;
ok1(*iter == '0');
*iter = '1';
}
ok1(i == NUM); ok1(i == NUM);
for (i = NUM-1; i >= 0; i--) { check_children(NULL, '1');
ok1(*p[i] == '1'); for (i = NUM-1; i >= 0; i--)
tal_free(p[i]); tal_free(p[i]);
}
tal_cleanup(); tal_cleanup();
return exit_status(); return exit_status();
} }
...@@ -48,7 +48,7 @@ int main(void) ...@@ -48,7 +48,7 @@ int main(void)
(size_t)-1UL / sizeof(int) / 2); (size_t)-1UL / sizeof(int) / 2);
ok1(!pi); ok1(!pi);
ok1(error_count == 4); ok1(error_count == 4);
ok1(tal_first(NULL) == origpi && !tal_next(NULL, origpi)); ok1(tal_first(NULL) == origpi && !tal_next(origpi) && !tal_first(origpi));
tal_free(origpi); tal_free(origpi);
/* Now, check that with taltk() we free old one on failure. */ /* Now, check that with taltk() we free old one on failure. */
......
...@@ -25,7 +25,7 @@ int main(void) ...@@ -25,7 +25,7 @@ int main(void)
/* Iteration test. */ /* Iteration test. */
i = 0; i = 0;
for (p = tal_first(parent); p; p = tal_next(parent, p)) { for (p = tal_first(parent); p; p = tal_next(p)) {
*p = '1'; *p = '1';
i++; i++;
} }
......
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