Fix shadowing in sequencer iterator

The __LINE__ was not properly expanded.
This commit is contained in:
Sergey Sharybin 2021-08-27 14:44:12 +02:00
parent c88ba461cf
commit 57e8714b38
1 changed files with 17 additions and 5 deletions

View File

@ -34,12 +34,24 @@ struct GSet;
struct GSetIterator;
struct Sequence;
#define SEQ_ITERATOR_FOREACH_IMPL(var, collection, suffix) \
for (SeqIterator iter##suffix = {{{NULL}}}; \
SEQ_iterator_ensure(collection, &iter##suffix, &var) && var != NULL; \
var = SEQ_iterator_yield(&iter##suffix))
/* Utility macro to construct an unique (within a file) variable name for iterator macro.
* Use indirect macro evaluation to ensure the `__LINE__` is expanded (rather than being
* treated as a name token),
*
* The `__LINE__` is defined at the invocation of the `SEQ_ITERATOR_FOREACH` and is not changed
* afterwards. This makes it safe to expand it several times in the `SEQ_ITERATOR_FOREACH`.
*
* This allows to have nested foreach loops.
*
* NOTE: Putting nested loop to a wrapper macro is not supported. */
#define _SEQ_ITERATOR_NAME_JOIN(x, y) x##_##y
#define _SEQ_ITERATOR_NAME_EVALUATE(x, y) _SEQ_ITERATOR_NAME_JOIN(x, y)
#define _SEQ_ITERATOR_NAME(prefix) _SEQ_ITERATOR_NAME_EVALUATE(prefix, __LINE__)
#define SEQ_ITERATOR_FOREACH(var, collection) SEQ_ITERATOR_FOREACH_IMPL(var, collection, __LINE__)
#define SEQ_ITERATOR_FOREACH(var, collection) \
for (SeqIterator _SEQ_ITERATOR_NAME(iter) = {{{NULL}}}; \
SEQ_iterator_ensure(collection, &_SEQ_ITERATOR_NAME(iter), &var) && var != NULL; \
var = SEQ_iterator_yield(&_SEQ_ITERATOR_NAME(iter)))
typedef struct SeqCollection {
struct GSet *set;