From bc1f54b0fc4582f3752f8b4add86c91be488851d Mon Sep 17 00:00:00 2001 From: Christopher Faulet Date: Mon, 23 Mar 2020 14:13:26 +0100 Subject: [PATCH] MINOR: mini-clist: Add functions to iterate backward on a list list_for_each_entry_rev() and list_for_each_entry_from_rev() and corresponding safe versions have been added to iterate on a list in the reverse order. All these functions work the same way than the forward versions, except they use the .p field to move for an element to another. --- include/common/mini-clist.h | 47 +++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/include/common/mini-clist.h b/include/common/mini-clist.h index 589a1d9fe..5d3954cd4 100644 --- a/include/common/mini-clist.h +++ b/include/common/mini-clist.h @@ -211,6 +211,53 @@ struct cond_wordlist { &item->member != (list_head); \ item = back, back = LIST_ELEM(back->member.n, typeof(back), member)) +/* + * Iterate backwards through a list of items of type "typeof(*item)" + * which are linked via a "struct list" member named . A pointer to + * the head of the list is passed in . No temporary variable is + * needed. Note that must not be modified during the loop. + * Example: list_for_each_entry_rev(cur_acl, known_acl, list) { ... }; + */ +#define list_for_each_entry_rev(item, list_head, member) \ + for (item = LIST_ELEM((list_head)->p, typeof(item), member); \ + &item->member != (list_head); \ + item = LIST_ELEM(item->member.p, typeof(item), member)) + +/* + * Same as list_for_each_entry_rev but starting from current point + * Iterate backwards through the list starting from + * It's basically the same macro but without initializing item to the head of + * the list. + */ +#define list_for_each_entry_from_rev(item, list_head, member) \ + for ( ; &item->member != (list_head); \ + item = LIST_ELEM(item->member.p, typeof(item), member)) + +/* + * Iterate backwards through a list of items of type "typeof(*item)" + * which are linked via a "struct list" member named . A pointer to + * the head of the list is passed in . A temporary variable + * of same type as is needed so that may safely be deleted + * if needed. + * Example: list_for_each_entry_safe_rev(cur_acl, tmp, known_acl, list) { ... }; + */ +#define list_for_each_entry_safe_rev(item, back, list_head, member) \ + for (item = LIST_ELEM((list_head)->p, typeof(item), member), \ + back = LIST_ELEM(item->member.p, typeof(item), member); \ + &item->member != (list_head); \ + item = back, back = LIST_ELEM(back->member.p, typeof(back), member)) + +/* + * Same as list_for_each_entry_safe_rev but starting from current point + * Iterate backwards through the list starting from + * It's basically the same macro but without initializing item to the head of + * the list. + */ +#define list_for_each_entry_safe_from_rev(item, back, list_head, member) \ + for (back = LIST_ELEM(item->member.p, typeof(item), member); \ + &item->member != (list_head); \ + item = back, back = LIST_ELEM(back->member.p, typeof(back), member)) + #include #define MT_LIST_BUSY ((struct mt_list *)1)