diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2015-06-14 00:23:39 +1000 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2015-06-14 00:25:24 +1000 |
commit | d448f12d07c5b65d5db29f207de3178490f8360d (patch) | |
tree | 4296d6d0cf06b616d20fe5327017cc0b26ff8cc6 | |
parent | c7a7fc0a1771394534cafaa7c30aa215631efc82 (diff) |
lstack: Allow a stack to be initialized from an existing top element
There are occasional cases where you might construct a valid stack, and
retain a direct pointer to the top element, but not the struct lstack
used to build it.
This patch adds a new lstack_init_from_top() macro to reconstruct a valid
struct lstack from the element pointer for cases like this.
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
-rw-r--r-- | ccan/lstack/lstack.h | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/ccan/lstack/lstack.h b/ccan/lstack/lstack.h index 41a9f05a..7eb880a5 100644 --- a/ccan/lstack/lstack.h +++ b/ccan/lstack/lstack.h @@ -51,6 +51,33 @@ struct lstack { struct lstack name = { NULL, } /** + * lstack_init_from_top - initialize a stack with a given top element + * @s: the lstack to initialize + * @e: pointer to the top element of the new stack + * @member: member of the element containing the lstack_link + * + * USE WITH CAUTION: This is for handling unusual cases where you have + * a pointer to an element in a previously constructed stack but can't + * conveniently pass around a normal struct lstack. Usually you + * should use lstack_init(). + * + * Example: + * LSTACK(stack1); + * struct lstack stack2; + * struct element { + * int value; + * struct lstack_link link; + * } el; + * + * lstack_push(&stack1, &el, link); + * + * lstack_init_from_top(&stack2, + * lstack_top(&stack1, struct element, link), link); + */ +#define lstack_init_from_top(s, e, member) \ + (lstack_init_((s), &(e)->member)) + +/** * lstack_init - initialize a stack * @h: the lstack to set to an empty stack * @@ -58,9 +85,11 @@ struct lstack { * struct lstack *sp = malloc(sizeof(*sp)); * lstack_init(sp); */ -static inline void lstack_init(struct lstack *s) +#define lstack_init(s) \ + (lstack_init_((s), NULL)) +static inline void lstack_init_(struct lstack *s, struct lstack_link *top) { - s->top = NULL; + s->top = top; } /** |