[Swan-dev] FOR_EACH_LIST_ENTRY_
D. Hugh Redelmeier
hugh at mimosa.com
Sun Dec 9 17:59:17 UTC 2018
I find this macro almost impenetrable.
I think that this is mainly due to it being contorted to make it look like
the head of a for statement: the code to be iterated over follows the
macro invocation.
If we passed that code to the macro, I think that the macro could be a lot
simpler and clearer.
Here's my stab at it. Perhaps I've misunderstood something about the
original and thus may have it wrong.
Comments?
==== original ====
#define FOR_EACH_LIST_ENTRY_(HEAD, DATA, NEXT) \
\
/* set head_ = HEAD (evaluate once) */ \
for (struct list_head *head_ = HEAD; \
head_ != NULL; head_ = NULL) \
\
/* set entry = head.NEXT; skip empty */ \
for (struct list_entry *entry_ = head_->head.NEXT; \
entry_ != &head_->head; entry_ = &head_->head) \
\
/* DATA = ENTRY->data; ENTRY = ENTRY->NEXT */ \
for (DATA = (typeof(DATA))entry_->data, \
entry_ = entry_->NEXT; \
DATA != NULL; \
DATA = (typeof(DATA))entry_->data, \
entry_ = entry_->NEXT)
==== replacement ====
/* traverse doubly-linked list
*
* The HEAD entry is a dummy.
* It exists even when the list is empty.
* It is distinguished by a NULL data field.
*/
#define FOR_EACH_LIST_ENTRY_(head, DATA, NEXT, BODY) \
for (struct list_entry *entry_ = (HEAD); ; ) { \
entry_ = entry_->NEXT; \
DATA = (typeof(DATA))entry_->data; \
if (DATA == NULL) \
break; \
{ BODY ; } \
}
More information about the Swan-dev
mailing list