Bug #118 ยป 0027-Avoid-VLA-use-in-generic_iterate-in-C-code.patch
| utility/iterator.h | ||
|---|---|---|
|
#ifdef __cplusplus
|
||
|
extern "C" {
|
||
|
#include "mem.h"
|
||
|
#endif /* __cplusplus */
|
||
|
/* utility */
|
||
| ... | ... | |
|
first element in the sequence, or an invalid iterator.
|
||
|
... - Zero or more extra arguments that 'FUNC_init' expects.
|
||
|
***************************************************************************/
|
||
|
#define generic_iterate(TYPE_it, TYPE_a, NAME_a, FUNC_size, FUNC_init, ...)\
|
||
|
do {\
|
||
|
char MY_mem_##NAME_a[FUNC_size()];\
|
||
|
struct iterator *MY_it_##NAME_a;\
|
||
|
TYPE_a NAME_a;\
|
||
|
MY_it_##NAME_a =\
|
||
|
FUNC_init((TYPE_it *) (void *) MY_mem_##NAME_a , ## __VA_ARGS__);\
|
||
|
for (; iterator_valid(MY_it_##NAME_a); iterator_next(MY_it_##NAME_a)) {\
|
||
|
NAME_a = (TYPE_a) iterator_get(MY_it_##NAME_a);\
|
||
|
#define generic_iterate_end\
|
||
|
}\
|
||
|
#ifdef __cplusplus
|
||
|
/* C++ does not have VLA, except as compiler extension in case of
|
||
|
some compilers. Thus we need to fc_malloc() correct size array.
|
||
|
Wrap the allocated array within a class, so it will get freed
|
||
|
by the destructor when it goes out of scope. */
|
||
|
class gi_mem
|
||
|
{
|
||
|
public:
|
||
|
void *array;
|
||
|
gi_mem(int size) {
|
||
|
array = fc_malloc(size);
|
||
|
}
|
||
|
~gi_mem() {
|
||
|
free(array);
|
||
|
}
|
||
|
};
|
||
|
#define generic_iterate(TYPE_it, TYPE_a, NAME_a, FUNC_size, FUNC_init, ...) \
|
||
|
do { \
|
||
|
gi_mem MY_mem_##NAME_a(FUNC_size()); \
|
||
|
struct iterator *MY_it_##NAME_a; \
|
||
|
TYPE_a NAME_a; \
|
||
|
MY_it_##NAME_a = \
|
||
|
FUNC_init((TYPE_it *) MY_mem_##NAME_a.array , ## __VA_ARGS__); \
|
||
|
for (; iterator_valid(MY_it_##NAME_a); iterator_next(MY_it_##NAME_a)) { \
|
||
|
NAME_a = (TYPE_a) iterator_get(MY_it_##NAME_a);
|
||
|
#else // __cplusplus
|
||
|
#define generic_iterate(TYPE_it, TYPE_a, NAME_a, FUNC_size, FUNC_init, ...) \
|
||
|
do { \
|
||
|
char MY_mem_##NAME_a[FUNC_size()]; \
|
||
|
struct iterator *MY_it_##NAME_a; \
|
||
|
TYPE_a NAME_a; \
|
||
|
MY_it_##NAME_a = \
|
||
|
FUNC_init((TYPE_it *) (void *) MY_mem_##NAME_a , ## __VA_ARGS__); \
|
||
|
for (; iterator_valid(MY_it_##NAME_a); iterator_next(MY_it_##NAME_a)) { \
|
||
|
NAME_a = (TYPE_a) iterator_get(MY_it_##NAME_a);
|
||
|
#endif // __cplusplus
|
||
|
#define generic_iterate_end \
|
||
|
} \
|
||
|
} while (FALSE)
|
||
|
/***************************************************************************
|
||