summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2023-10-12 13:18:00 -0400
committerTavian Barnes <tavianator@tavianator.com>2023-10-12 13:20:27 -0400
commit1addab1e5f12cb0fddfa92872bf45653352cc212 (patch)
tree4c81c43119d568ac3a4539b87a00e17b0b9f57f3
parentda5c9dd34f65989c842cfb831b8592157dd8ed34 (diff)
downloadbfs-1addab1e5f12cb0fddfa92872bf45653352cc212.tar.xz
list: Assert that we're not inserting already-attached nodes
-rw-r--r--src/list.h66
-rw-r--r--src/trie.c1
2 files changed, 46 insertions, 21 deletions
diff --git a/src/list.h b/src/list.h
index 5587543..61c22e3 100644
--- a/src/list.h
+++ b/src/list.h
@@ -82,6 +82,7 @@
#ifndef BFS_LIST_H
#define BFS_LIST_H
+#include "diag.h"
#include <stddef.h>
#include <string.h>
@@ -206,6 +207,27 @@
(SLIST_CHECK_(list), !list->head)
/**
+ * Check if an item is attached to a singly-linked list.
+ *
+ * @param list
+ * The list to check.
+ * @param item
+ * The item to check.
+ * @param node (optional)
+ * If specified, use item->node.next rather than item->next.
+ * @return
+ * Whether the item is attached to the list.
+ */
+#define SLIST_ATTACHED(list, ...) \
+ SLIST_ATTACHED_(list, __VA_ARGS__, )
+
+#define SLIST_ATTACHED_(list, item, ...) \
+ SLIST_ATTACHED__((list), (item), LIST_NEXT_(__VA_ARGS__))
+
+#define SLIST_ATTACHED__(list, item, next) \
+ (item->next || list->tail == &item->next)
+
+/**
* Insert an item into a singly-linked list.
*
* @param list
@@ -224,6 +246,7 @@
SLIST_INSERT__((list), (cursor), (item), LIST_NEXT_(__VA_ARGS__))
#define SLIST_INSERT__(list, cursor, item, next) LIST_VOID_( \
+ bfs_assert(!SLIST_ATTACHED__(list, item, next)), \
item->next = *cursor, \
*cursor = item, \
list->tail = item->next ? list->tail : &item->next)
@@ -426,6 +449,27 @@ static inline void *slist_remove_impl(void *ret, void *cursor, void *next, void
LIST_INSERT(list, NULL, __VA_ARGS__)
/**
+ * Check if an item is attached to a doubly-linked list.
+ *
+ * @param list
+ * The list to check.
+ * @param item
+ * The item to check.
+ * @param node (optional)
+ * If specified, use item->node.{prev,next} rather than item->{prev,next}.
+ * @return
+ * Whether the item is attached to the list.
+ */
+#define LIST_ATTACHED(list, ...) \
+ LIST_ATTACHED_(list, __VA_ARGS__, )
+
+#define LIST_ATTACHED_(list, item, ...) \
+ LIST_ATTACHED__((list), (item), LIST_PREV_(__VA_ARGS__), LIST_NEXT_(__VA_ARGS__))
+
+#define LIST_ATTACHED__(list, item, prev, next) \
+ (item->prev || item->next || list->head == item || list->tail == item)
+
+/**
* Insert into a doubly-linked list after the given cursor.
*
* @param list
@@ -444,6 +488,7 @@ static inline void *slist_remove_impl(void *ret, void *cursor, void *next, void
LIST_INSERT__((list), (cursor), (item), LIST_PREV_(__VA_ARGS__), LIST_NEXT_(__VA_ARGS__))
#define LIST_INSERT__(list, cursor, item, prev, next) LIST_VOID_( \
+ bfs_assert(!LIST_ATTACHED__(list, item, prev, next)), \
item->prev = cursor, \
item->next = cursor ? cursor->next : list->head, \
*(item->prev ? &item->prev->next : &list->head) = item, \
@@ -471,27 +516,6 @@ static inline void *slist_remove_impl(void *ret, void *cursor, void *next, void
item->prev = item->next = NULL)
/**
- * Check if an item is attached to a doubly-linked list.
- *
- * @param list
- * The list to check.
- * @param item
- * The item to check.
- * @param node (optional)
- * If specified, use item->node.{prev,next} rather than item->{prev,next}.
- * @return
- * Whether the item is attached to the list.
- */
-#define LIST_ATTACHED(list, ...) \
- LIST_ATTACHED_(list, __VA_ARGS__, )
-
-#define LIST_ATTACHED_(list, item, ...) \
- LIST_ATTACHED__((list), (item), LIST_PREV_(__VA_ARGS__), LIST_NEXT_(__VA_ARGS__))
-
-#define LIST_ATTACHED__(list, item, prev, next) \
- (item->prev || item->next || list->head == item || list->tail == item)
-
-/**
* Loop over the items in a doubly-linked list.
*
* @param type
diff --git a/src/trie.c b/src/trie.c
index 55544e6..23b70ff 100644
--- a/src/trie.c
+++ b/src/trie.c
@@ -325,6 +325,7 @@ static struct trie_leaf *trie_leaf_alloc(struct trie *trie, const void *key, siz
return NULL;
}
+ LIST_ITEM_INIT(leaf);
LIST_APPEND(trie, leaf);
leaf->value = NULL;