1 #if !HAVE_COMPOUND_LITERALS || !HAVE_FOR_LOOP_DECLARATION
2 #include <ccan/foreach/foreach.h>
3 #include <ccan/list/list.h>
8 /* This list is normally very short. */
9 static LIST_HEAD(iters);
12 struct list_node list;
17 static void free_old_iters(const void *index)
19 struct iter_info *i, *next;
21 list_for_each_safe(&iters, i, next, list) {
22 /* If we're re-using an index, free the old one.
23 * Otherwise, if it's past i on the stack, it's old. Don't
24 * assume stack direction, but we know index is downstack. */
26 || (((uintptr_t)index < (uintptr_t)&i)
27 == ((uintptr_t)&i < (uintptr_t)i->index))) {
34 static struct iter_info *find_iter(const void *index)
38 list_for_each(&iters, i, list) {
39 if (i->index == index)
45 static struct iter_info *new_iter(const void *index)
47 struct iter_info *info = malloc(sizeof *info);
49 info->i = info->num = 0;
50 list_add(&iters, &info->list);
54 #if HAVE_COMPOUND_LITERALS
55 void _foreach_iter_init(const void *i)
61 unsigned int _foreach_iter(const void *i)
63 struct iter_info *info = find_iter(i);
67 unsigned int _foreach_iter_inc(const void *i)
69 struct iter_info *info = find_iter(i);
72 #else /* Don't have compound literals... */
73 int _foreach_term = 0x42430199;
75 /* We count values at beginning, and every time around the loop. We change
76 * the terminator each time, so we don't get fooled in case it really appears
78 static unsigned int count_vals(struct iter_info *info, va_list *ap)
83 for (i = 0; i < info->num || val != _foreach_term; i++) {
84 val = va_arg(*ap, int);
90 int _foreach_intval_init(const void *i, int val, ...)
93 struct iter_info *info;
99 info->num = count_vals(info, &ap);
105 bool _foreach_intval_done(const void *i)
107 struct iter_info *info = find_iter(i);
108 return info->i == info->num;
111 int _foreach_intval_next(const void *i, int val, ...)
113 struct iter_info *info = find_iter(i);
118 info->num = count_vals(info, &ap);
122 assert(info->i <= info->num);
123 if (info->i == info->num)
127 for (num = 0; num < info->i; num++)
128 val = va_arg(ap, int);
134 void *_foreach_ptrval_init(const void *i, const void *val, ...)
136 struct iter_info *info;
144 void *_foreach_ptrval_next(const void *i, const void *val, ...)
146 struct iter_info *info = find_iter(i);
152 for (num = 0; num < info->i; num++)
153 val = va_arg(ap, void *);
157 #endif /* !HAVE_COMPOUND_LITERALS */
158 #endif /* !HAVE_COMPOUND_LITERALS || !HAVE_FOR_LOOP_DECLARATION */