diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2023-03-29 13:25:18 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2023-03-29 13:25:18 -0400 |
commit | f75f3de63888702f29f48bcf2691291403720b9d (patch) | |
tree | 40d77d87299b8d54fb5d8e8b059c4a216cd4d353 /src | |
parent | 116ab1ed2b4230aea1ab634618af3162cabbb37f (diff) | |
download | bfs-f75f3de63888702f29f48bcf2691291403720b9d.tar.xz |
list: New helper macros for converting entries to items
Diffstat (limited to 'src')
-rw-r--r-- | src/bftw.c | 18 | ||||
-rw-r--r-- | src/list.h | 63 |
2 files changed, 65 insertions, 16 deletions
@@ -69,14 +69,8 @@ struct bftw_file { }; /** Move from a list entry to a bftw_file. */ -static struct bftw_file *bftw_file_entry(struct slink *link) { - return BFS_CONTAINER_OF(link, struct bftw_file, link); -} - -/** Move from an LRU entry to a bftw_file. */ -static struct bftw_file *bftw_lru_file(struct link *link) { - return BFS_CONTAINER_OF(link, struct bftw_file, lru); -} +#define BFTW_FILE(...) \ + LIST_ITEM(struct bftw_file, __VA_ARGS__) /** * A cache of open directories. @@ -126,7 +120,7 @@ static int bftw_cache_pop(struct bftw_cache *cache) { return -1; } - struct bftw_file *file = bftw_lru_file(cache->list.tail); + struct bftw_file *file = BFTW_FILE(cache->list.tail, lru); bftw_file_close(cache, file); return 0; } @@ -810,7 +804,7 @@ static int bftw_pop(struct bftw_state *state) { return 0; } - state->file = bftw_file_entry(slist_pop(&state->queue)); + state->file = BFTW_FILE(slist_pop(&state->queue)); if (bftw_build_path(state) != 0) { return -1; @@ -974,9 +968,7 @@ static int bftw_state_destroy(struct bftw_state *state) { /** Comparison function for BFTW_SORT. */ static bool bftw_file_cmp(struct slink *left, struct slink *right, const void *ptr) { - struct bftw_file *lfile = bftw_file_entry(left); - struct bftw_file *rfile = bftw_file_entry(right); - return strcoll(lfile->name, rfile->name) <= 0; + return strcoll(BFTW_FILE(left)->name, BFTW_FILE(right)->name) <= 0; } /** Finish adding a batch of files. */ @@ -107,10 +107,67 @@ struct link *list_pop(struct list *list); /** Check if a link is attached to a list. */ bool list_attached(const struct list *list, const struct link *link); +// LIST_ITEM() helper +#define LIST_ITEM_IMPL(type, entry, member, ...) \ + BFS_CONTAINER_OF(entry, type, member) + +/** + * Convert a list entry to its container. + * + * @param type + * The type of the list entries. + * @param entry + * The list entry to convert. + * @param member + * The name of the list link field (default: link). + * @return + * The item that contains the given entry. + */ +#define LIST_ITEM(...) \ + LIST_ITEM_IMPL(__VA_ARGS__, link,) + +// LIST_NEXT() helper +#define LIST_NEXT_IMPL(type, entry, member, ...) \ + LIST_ITEM(type, (entry)->member.next, member) + +/** + * Get the next item in a list. + * + * @param type + * The type of the list entries. + * @param entry + * The current entry. + * @param member + * The name of the list link field (default: link). + * @return + * The next item in the list. + */ +#define LIST_NEXT(...) \ + LIST_NEXT_IMPL(__VA_ARGS__, link,) + +// LIST_PREV() helper +#define LIST_PREV_IMPL(type, entry, member, ...) \ + LIST_ITEM(type, (entry)->member.prev, member) + +/** + * Get the previous entry in a list. + * + * @param type + * The type of the list entries. + * @param entry + * The current entry. + * @param member + * The name of the list link field (default: link). + * @return + * The previous item in the list. + */ +#define LIST_PREV(...) \ + LIST_PREV_IMPL(__VA_ARGS__, link,) + // Helper for LIST_FOR_EACH_*() #define LIST_FOR_EACH_IMPL(entry, type, i, member, ...) \ - for (type *_next, *i = BFS_CONTAINER_OF(entry, type, member); \ - i && (_next = BFS_CONTAINER_OF(i->member.next, type, member), true); \ + for (type *_next, *i = LIST_ITEM(type, entry, member); \ + i && (_next = LIST_NEXT(type, i, member), true); \ i = _next) /** @@ -150,7 +207,7 @@ bool list_attached(const struct list *list, const struct link *link); // Helper for LIST_DRAIN() #define LIST_DRAIN_IMPL(list, type, i, member, ...) \ - for (type *i; (i = BFS_CONTAINER_OF(LIST_POP(list), type, member));) + for (type *i; (i = LIST_ITEM(type, LIST_POP(list), member));) /** * Drain the entries from a list. |