Browse Source

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>
David Gibson 10 years ago
parent
commit
d448f12d07
1 changed files with 31 additions and 2 deletions
  1. 31 2
      ccan/lstack/lstack.h

+ 31 - 2
ccan/lstack/lstack.h

@@ -50,6 +50,33 @@ struct lstack {
 #define LSTACK(name) \
 	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;
 }
 
 /**