summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2015-06-14 00:23:39 +1000
committerDavid Gibson <david@gibson.dropbear.id.au>2015-06-14 00:25:24 +1000
commitd448f12d07c5b65d5db29f207de3178490f8360d (patch)
tree4296d6d0cf06b616d20fe5327017cc0b26ff8cc6
parentc7a7fc0a1771394534cafaa7c30aa215631efc82 (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.h33
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;
}
/**