diff options
author | Petr Machata <pmachata@redhat.com> | 2012-09-25 14:52:23 +0200 |
---|---|---|
committer | Petr Machata <pmachata@redhat.com> | 2012-09-25 14:52:23 +0200 |
commit | 49d3d52e19692f92cf2114b053053c549a723b79 (patch) | |
tree | e9360bd50c2d36695efea2cbeb2000422428e00a | |
parent | a24021c5abfa8c2482e3224f14ac191cd0826a8f (diff) | |
download | ltrace-49d3d52e19692f92cf2114b053053c549a723b79.tar.gz |
Add vect_each, VECT_EACH for iteration over vectors
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | vect.c | 22 | ||||
-rw-r--r-- | vect.h | 21 |
3 files changed, 48 insertions, 0 deletions
@@ -1,5 +1,10 @@ 2012-09-25 Petr Machata <pmachata@redhat.com> + * vect.h, vect.c (vect_each): New function. + * vect.h (VECT_EACH): New wrapper macro. + +2012-09-25 Petr Machata <pmachata@redhat.com> + * callback.h: New file. * proc.h (enum callback_status): Move to callback.h. @@ -134,3 +134,25 @@ vect_destroy(struct vect *vec, void (*dtor)(void *emt, void *data), void *data) } free(vec->data); } + +void * +vect_each(struct vect *vec, void *start_after, + enum callback_status (*cb)(void *, void *), void *data) +{ + size_t i = start_after == NULL ? 0 + : ((start_after - vec->data) / vec->elt_size) + 1; + + for (; i < vec->size; ++i) { + void *slt = slot(vec, i); + switch ((*cb)(slt, data)) { + case CBS_FAIL: + /* XXX handle me */ + case CBS_STOP: + return slt; + case CBS_CONT: + break; + } + } + + return NULL; +} @@ -22,6 +22,9 @@ #define VECT_H #include <stddef.h> +#include <assert.h> + +#include "callback.h" /* Vector is an array that can grow as needed to accommodate the data * that it needs to hold. ELT_SIZE is also used as an elementary @@ -122,4 +125,22 @@ void vect_destroy(struct vect *vec, DATA); \ } while (0) +/* Iterate through vector VEC. See callback.h for notes on iteration + * interfaces. */ +void *vect_each(struct vect *vec, void *start_after, + enum callback_status (*cb)(void *, void *), void *data); + +#define VECT_EACH(VECP, ELT_TYPE, START_AFTER, CB, DATA) \ + /* xxx GCC-ism necessary to get in the safety latches. */ \ + ({ \ + assert((VECP)->elt_size == sizeof(ELT_TYPE)); \ + /* Check that CB is typed properly. */ \ + enum callback_status (*_cb)(ELT_TYPE *, void *) = CB; \ + ELT_TYPE *start_after = (START_AFTER); \ + (ELT_TYPE *)vect_each((VECP), start_after, \ + (enum callback_status \ + (*)(void *, void *))_cb, \ + DATA); \ + }) + #endif /* VECT_H */ |