From cf2eb17c48a23d49bf517df58e34e30529c16576 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 19 Sep 2024 12:14:06 -0400 Subject: list: New drain_slist() macro --- src/bftw.c | 11 ++++++----- src/expr.c | 3 +-- src/list.h | 27 +++++++++++++++++++++++++++ src/opt.c | 47 +++++++++++++++-------------------------------- 4 files changed, 49 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/bftw.c b/src/bftw.c index 64991b0..0186e3f 100644 --- a/src/bftw.c +++ b/src/bftw.c @@ -1162,12 +1162,13 @@ static int bftw_file_open(struct bftw_state *state, struct bftw_file *file, cons struct bftw_list parents; SLIST_INIT(&parents); - struct bftw_file *cur; - for (cur = file; cur != base; cur = cur->parent) { + // Reverse the chain of parents + for (struct bftw_file *cur = file; cur != base; cur = cur->parent) { SLIST_PREPEND(&parents, cur); } - while ((cur = SLIST_POP(&parents))) { + // Open each component relative to its parent + drain_slist (struct bftw_file, cur, &parents) { if (!cur->parent || cur->parent->fd >= 0) { bftw_file_openat(state, cur, cur->parent, cur->name); } @@ -1870,8 +1871,8 @@ static int bftw_gc(struct bftw_state *state, enum bftw_gc_flags flags) { } state->direrror = 0; - while ((file = SLIST_POP(&state->to_close, ready))) { - bftw_unwrapdir(state, file); + drain_slist (struct bftw_file, dead, &state->to_close, ready) { + bftw_unwrapdir(state, dead); } enum bftw_gc_flags visit = BFTW_VISIT_FILE; diff --git a/src/expr.c b/src/expr.c index 110e9b7..ca37ffc 100644 --- a/src/expr.c +++ b/src/expr.c @@ -68,8 +68,7 @@ void bfs_expr_append(struct bfs_expr *expr, struct bfs_expr *child) { } void bfs_expr_extend(struct bfs_expr *expr, struct bfs_exprs *children) { - while (!SLIST_EMPTY(children)) { - struct bfs_expr *child = SLIST_POP(children); + drain_slist (struct bfs_expr, child, children) { bfs_expr_append(expr, child); } } diff --git a/src/list.h b/src/list.h index b30a96e..50c06a0 100644 --- a/src/list.h +++ b/src/list.h @@ -428,6 +428,33 @@ static inline void *slist_remove_impl(void *ret, void *cursor, void *next, size_ item && (SLIST_CHECK_(list), _next = item->next, true); \ item = _next) +/** + * Loop over a singly-linked list, popping each item. + * + * @param type + * The list item type. + * @param item + * The induction variable name. + * @param list + * The list to drain. + * @param node (optional) + * If specified, use head->node.next rather than head->next. + */ +#define drain_slist(type, item, ...) \ + drain_slist_(type, item, __VA_ARGS__, ) + +#define drain_slist_(type, item, list, ...) \ + drain_slist__(type, item, (list), LIST_NEXT_(__VA_ARGS__)) + +#define drain_slist__(type, item, list, next) \ + for (type *item = list->head; item && \ + (SLIST_CHECK_(list), \ + list->head = item->next, \ + list->tail = list->head ? list->tail : &list->head, \ + item->next = NULL, \ + true); \ + item = list->head) + /** * Initialize a doubly-linked list. * diff --git a/src/opt.c b/src/opt.c index 9d4323d..aa41a6a 100644 --- a/src/opt.c +++ b/src/opt.c @@ -737,9 +737,7 @@ static struct bfs_expr *visit_and(struct bfs_opt *opt, struct bfs_expr *expr, co df_init_bottom(&opt->after_false); struct bfs_opt nested = *opt; - while (!SLIST_EMPTY(&children)) { - struct bfs_expr *child = SLIST_POP(&children); - + drain_slist (struct bfs_expr, child, &children) { if (SLIST_EMPTY(&children)) { nested.ignore_result = opt->ignore_result; } else { @@ -771,9 +769,7 @@ static struct bfs_expr *visit_or(struct bfs_opt *opt, struct bfs_expr *expr, con df_init_bottom(&opt->after_true); struct bfs_opt nested = *opt; - while (!SLIST_EMPTY(&children)) { - struct bfs_expr *child = SLIST_POP(&children); - + drain_slist (struct bfs_expr, child, &children) { if (SLIST_EMPTY(&children)) { nested.ignore_result = opt->ignore_result; } else { @@ -803,9 +799,7 @@ static struct bfs_expr *visit_comma(struct bfs_opt *opt, struct bfs_expr *expr, struct bfs_opt nested = *opt; - while (!SLIST_EMPTY(&children)) { - struct bfs_expr *child = SLIST_POP(&children); - + drain_slist (struct bfs_expr, child, &children) { if (SLIST_EMPTY(&children)) { nested.ignore_result = opt->ignore_result; } else { @@ -1384,8 +1378,7 @@ static struct bfs_expr *sink_not_andor(struct bfs_opt *opt, struct bfs_expr *exp struct bfs_exprs children; foster_children(expr, &children); - struct bfs_expr *child; - while ((child = SLIST_POP(&children))) { + drain_slist (struct bfs_expr, child, &children) { opt_enter(opt, "%pe\n", child); child = negate_expr(opt, child, argv); @@ -1412,8 +1405,7 @@ static struct bfs_expr *sink_not_comma(struct bfs_opt *opt, struct bfs_expr *exp struct bfs_exprs children; foster_children(expr, &children); - struct bfs_expr *child; - while ((child = SLIST_POP(&children))) { + drain_slist (struct bfs_expr, child, &children) { if (SLIST_EMPTY(&children)) { opt_enter(opt, "%pe\n", child); opt_debug(opt, "sink\n"); @@ -1463,8 +1455,7 @@ static struct bfs_expr *canonicalize_assoc(struct bfs_opt *opt, struct bfs_expr struct bfs_exprs flat; SLIST_INIT(&flat); - struct bfs_expr *child; - while ((child = SLIST_POP(&children))) { + drain_slist (struct bfs_expr, child, &children) { if (child->eval_fn == expr->eval_fn) { struct bfs_expr *head = SLIST_HEAD(&child->children); struct bfs_expr *tail = SLIST_TAIL(&child->children); @@ -1572,8 +1563,7 @@ static struct bfs_expr *reorder_andor(struct bfs_opt *opt, struct bfs_expr *expr struct bfs_exprs pure; SLIST_INIT(&pure); - struct bfs_expr *child; - while ((child = SLIST_POP(&children))) { + drain_slist (struct bfs_expr, child, &children) { if (child->pure) { SLIST_APPEND(&pure, child); } else { @@ -1975,8 +1965,7 @@ static struct bfs_expr *lift_andor_not(struct bfs_opt *opt, struct bfs_expr *exp struct bfs_exprs children; foster_children(expr, &children); - struct bfs_expr *child; - while ((child = SLIST_POP(&children))) { + drain_slist (struct bfs_expr, child, &children) { opt_enter(opt, "%pe\n", child); child = negate_expr(opt, child, &fake_not_arg); @@ -2022,9 +2011,7 @@ static struct bfs_expr *simplify_and(struct bfs_opt *opt, struct bfs_expr *expr, struct bfs_exprs children; foster_children(expr, &children); - while (!SLIST_EMPTY(&children)) { - struct bfs_expr *child = SLIST_POP(&children); - + drain_slist (struct bfs_expr, child, &children) { if (child == ignorable) { ignore = true; } @@ -2045,8 +2032,8 @@ static struct bfs_expr *simplify_and(struct bfs_opt *opt, struct bfs_expr *expr, bfs_expr_append(expr, child); if (child->always_false) { - while ((child = SLIST_POP(&children))) { - opt_delete(opt, "%pe [short-circuit]\n", child); + drain_slist (struct bfs_expr, dead, &children) { + opt_delete(opt, "%pe [short-circuit]\n", dead); } } } @@ -2071,9 +2058,7 @@ static struct bfs_expr *simplify_or(struct bfs_opt *opt, struct bfs_expr *expr, struct bfs_exprs children; foster_children(expr, &children); - while (!SLIST_EMPTY(&children)) { - struct bfs_expr *child = SLIST_POP(&children); - + drain_slist (struct bfs_expr, child, &children) { if (child == ignorable) { ignore = true; } @@ -2094,8 +2079,8 @@ static struct bfs_expr *simplify_or(struct bfs_opt *opt, struct bfs_expr *expr, bfs_expr_append(expr, child); if (child->always_true) { - while ((child = SLIST_POP(&children))) { - opt_delete(opt, "%pe [short-circuit]\n", child); + drain_slist (struct bfs_expr, dead, &children) { + opt_delete(opt, "%pe [short-circuit]\n", dead); } } } @@ -2117,9 +2102,7 @@ static struct bfs_expr *simplify_comma(struct bfs_opt *opt, struct bfs_expr *exp struct bfs_exprs children; foster_children(expr, &children); - while (!SLIST_EMPTY(&children)) { - struct bfs_expr *child = SLIST_POP(&children); - + drain_slist (struct bfs_expr, child, &children) { if (opt->level >= 2 && child->pure && !SLIST_EMPTY(&children)) { if (!opt_ignore(opt, child, true)) { return NULL; -- cgit v1.2.3