1 #include <ccan/foreach/foreach.h>
2 #if !HAVE_COMPOUND_LITERALS || !HAVE_FOR_LOOP_DECLARATION
3 #include <ccan/list/list.h>
8 /* This list is normally very short. */
9 static LIST_HEAD(iters);
12 struct list_node list;
18 /* Is pointer still downstack from some other onstack var? */
19 static bool on_stack(const void *ptr, const void *onstack)
21 #if HAVE_STACK_GROWS_UPWARDS
28 static void free_old_iters(const void *index)
30 struct iter_info *i, *next;
32 list_for_each_safe(&iters, i, next, list) {
33 /* If we're re-using an index, free the old one.
34 * Otherwise, discard if it's passed off stack. */
36 || (i->onstack && !on_stack(i->index, &i))) {
43 static struct iter_info *find_iter(const void *index)
47 list_for_each(&iters, i, list) {
48 if (i->index == index)
54 static struct iter_info *new_iter(const void *index)
56 struct iter_info *info = malloc(sizeof *info);
58 info->i = info->num = 0;
59 info->onstack = on_stack(index, &info);
60 list_add(&iters, &info->list);
64 #if HAVE_COMPOUND_LITERALS
65 void _foreach_iter_init(const void *i)
71 unsigned int _foreach_iter(const void *i)
73 struct iter_info *info = find_iter(i);
77 unsigned int _foreach_iter_inc(const void *i)
79 struct iter_info *info = find_iter(i);
82 #else /* Don't have compound literals... */
83 int _foreach_term = 0x42430199;
85 /* We count values at beginning, and every time around the loop. We change
86 * the terminator each time, so we don't get fooled in case it really appears
88 static unsigned int count_vals(struct iter_info *info, va_list *ap)
93 for (i = 0; i < info->num || val != _foreach_term; i++) {
94 val = va_arg(*ap, int);
100 int _foreach_intval_init(const void *i, int val, ...)
103 struct iter_info *info;
109 info->num = count_vals(info, &ap);
115 bool _foreach_intval_done(const void *i)
117 struct iter_info *info = find_iter(i);
118 return info->i == info->num;
121 int _foreach_intval_next(const void *i, int val, ...)
123 struct iter_info *info = find_iter(i);
128 info->num = count_vals(info, &ap);
132 assert(info->i <= info->num);
133 if (info->i == info->num)
137 for (num = 0; num < info->i; num++)
138 val = va_arg(ap, int);
144 void *_foreach_ptrval_init(const void *i, const void *val, ...)
146 struct iter_info *info;
154 void *_foreach_ptrval_next(const void *i, const void *val, ...)
156 struct iter_info *info = find_iter(i);
162 for (num = 0; num < info->i; num++)
163 val = va_arg(ap, void *);
167 #endif /* !HAVE_COMPOUND_LITERALS */
168 #endif /* !HAVE_COMPOUND_LITERALS || !HAVE_FOR_LOOP_DECLARATION */