Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey@blender.org>2021-08-27 15:44:12 +0300
committerSergey Sharybin <sergey@blender.org>2021-08-27 15:44:12 +0300
commit57e8714b381c37cc5e934ad0a166e5de208f8828 (patch)
tree3310859b226199687c802b7fed8bb0fce93d1fac
parentc88ba461cf7e271de16d6951c7b185b964a252b9 (diff)
Fix shadowing in sequencer iterator
The __LINE__ was not properly expanded.
-rw-r--r--source/blender/sequencer/SEQ_iterator.h22
1 files changed, 17 insertions, 5 deletions
diff --git a/source/blender/sequencer/SEQ_iterator.h b/source/blender/sequencer/SEQ_iterator.h
index 9fca25653e1..7eab9f84b50 100644
--- a/source/blender/sequencer/SEQ_iterator.h
+++ b/source/blender/sequencer/SEQ_iterator.h
@@ -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;