From eef75524aec3910097cb6923c30b898ad98179fe Mon Sep 17 00:00:00 2001
From: Tavian Barnes <tavianator@tavianator.com>
Date: Wed, 24 May 2023 11:54:33 -0400
Subject: list: Allow popping from an empty list

---
 src/bftw.c | 19 +++----------------
 src/list.h |  4 +++-
 2 files changed, 6 insertions(+), 17 deletions(-)

(limited to 'src')

diff --git a/src/bftw.c b/src/bftw.c
index 966f03d..916a56b 100644
--- a/src/bftw.c
+++ b/src/bftw.c
@@ -299,11 +299,10 @@ static int bftw_file_open(struct bftw_cache *cache, struct bftw_file *file, cons
 		SLIST_PREPEND(&parents, cur);
 	}
 
-	while ((cur = parents.head)) {
+	while ((cur = SLIST_POP(&parents))) {
 		if (!cur->parent || cur->parent->fd >= 0) {
 			bftw_file_openat(cache, cur, cur->parent, cur->name);
 		}
-		SLIST_POP(&parents);
 	}
 
 	return file->fd;
@@ -772,29 +771,17 @@ static enum bftw_action bftw_call_back(struct bftw_state *state, const char *nam
 static bool bftw_pop_dir(struct bftw_state *state) {
 	bfs_assert(!state->file);
 
-	if (!state->dirs.head) {
-		return false;
-	}
-
 	if (state->files.head && state->strategy == BFTW_BFS) {
 		return false;
 	}
 
-	state->file = SLIST_POP(&state->dirs);
-	return true;
+	return (state->file = SLIST_POP(&state->dirs));
 }
 
 /** Pop a file to visit from the queue. */
 static bool bftw_pop_file(struct bftw_state *state) {
 	bfs_assert(!state->file);
-
-	state->file = state->files.head;
-	if (state->file) {
-		SLIST_POP(&state->files);
-		return true;
-	} else {
-		return false;
-	}
+	return (state->file = SLIST_POP(&state->files));
 }
 
 /**
diff --git a/src/list.h b/src/list.h
index 89f00ed..a284c25 100644
--- a/src/list.h
+++ b/src/list.h
@@ -280,11 +280,13 @@ static inline void *slist_remove_impl(void *ret, void *cursor, void *next, void
  *         The list to pop from.
  * @param node (optional)
  *         If specified, use head->node.next rather than head->next.
+ * @return
+ *         The popped item, or NULL if the list was empty.
  */
 #define SLIST_POP(...) SLIST_POP_(__VA_ARGS__, )
 
 #define SLIST_POP_(list, ...) \
-	SLIST_REMOVE_(list, &(list)->head, __VA_ARGS__)
+	((list)->head ? SLIST_REMOVE_(list, &(list)->head, __VA_ARGS__) : NULL)
 
 /**
  * Initialize a doubly-linked list.
-- 
cgit v1.2.3