path = path_basename(ctx, take(tal_strdup(ctx, "..")));
ok1(streq(path, ".."));
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);
ok1(path_basename(ctx, take(NULL)) == NULL);
ok1(!tal_first(ctx));
ok1(strstarts(path, cwd));
ok1(path[strlen(cwd)] == PATH_SEP);
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");
ok1(streq(path2, path));
path = path_dirname(ctx, take(tal_strdup(ctx, "..")));
ok1(streq(path, "."));
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);
ok1(path_dirname(ctx, take(NULL)) == NULL);
ok1(!tal_first(ctx));
path = path_join(ctx, "foo", take(tal_strdup(ctx, "bar")));
ok1(streq(path, "foo/bar"));
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);
path = path_join(ctx, "foo", take(tal_strdup(ctx, "/bar")));
ok1(streq(path, "/bar"));
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);
path = path_join(ctx, take(tal_strdup(ctx, "foo")), "bar");
ok1(streq(path, "foo/bar"));
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);
path = path_join(ctx, take(tal_strdup(ctx, "foo")), "/bar");
ok1(streq(path, "/bar"));
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);
path = path_join(ctx, take(tal_strdup(ctx, "foo")),
take(tal_strdup(ctx, "bar")));
ok1(streq(path, "foo/bar"));
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);
path = path_join(ctx, take(tal_strdup(ctx, "foo")),
take(tal_strdup(ctx, "/bar")));
ok1(streq(path, "/bar"));
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);
path = path_join(ctx, take(NULL), "bar");
link = path_readlink(ctx, take(tal_strdup(ctx, "run-readlink-link")));
ok1(tal_parent(link) == ctx);
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");
ok1(!split);
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);
return exit_status();
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
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);
-
- return NULL;
+ head = &ignore_destroying_bit(prevhdr->parent_child)->children;
+ next = list_next(head, prevhdr, list);
+ if (!next)
+ return NULL;
+ return from_tal_hdr(next);
}
tal_t *tal_parent(const tal_t *ctx)
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.
*
* Returns NULL if there are no children.
tal_t *tal_first(const tal_t *root);
/**
- * tal_next - get the next tal object child.
- * @root: The tal allocated object to start with, or NULL.
+ * tal_next - get the next immediate tal object child.
* @prev: The return value from tal_first or tal_next.
*
- * Returns NULL if there are no more children. This should be safe to
- * call on an altering tree unless @prev is no longer a descendent of
- * @root.
+ * Returns NULL if there are no more immediate children. This should be safe to
+ * call on an altering tree unless @prev is no longer valid.
*/
-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.
ok1(a[1] == 1);
ok1(a[2] == 2);
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);
#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)
{
- char *p[NUM] = { NULL }, *iter;
+ char *p[NUM] = { NULL };
int i;
plan_tests(NUM + 1 + NUM);
*p[i] = '0';
}
- i = 0;
- for (iter = tal_first(NULL); iter; iter = tal_next(NULL, iter)) {
- i++;
- ok1(*iter == '0');
- *iter = '1';
- }
+ i = set_children(NULL, '1');
ok1(i == NUM);
- for (i = NUM-1; i >= 0; i--) {
- ok1(*p[i] == '1');
+ check_children(NULL, '1');
+ for (i = NUM-1; i >= 0; i--)
tal_free(p[i]);
- }
+
tal_cleanup();
return exit_status();
}
(size_t)-1UL / sizeof(int) / 2);
ok1(!pi);
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);
/* Now, check that with taltk() we free old one on failure. */
/* Iteration test. */
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';
i++;
}