summaryrefslogtreecommitdiff
path: root/vect.h
diff options
context:
space:
mode:
Diffstat (limited to 'vect.h')
-rw-r--r--vect.h71
1 files changed, 66 insertions, 5 deletions
diff --git a/vect.h b/vect.h
index 0f9951d..dd6dcd4 100644
--- a/vect.h
+++ b/vect.h
@@ -1,6 +1,6 @@
/*
* This file is part of ltrace.
- * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc.
+ * Copyright (C) 2011,2012,2013 Petr Machata, Red Hat Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -96,8 +96,32 @@ int vect_empty(const struct vect *vec);
* operation was successful, or negative value on error. */
int vect_pushback(struct vect *vec, void *eltp);
-/* Drop last element of VECP. */
-void vect_popback(struct vect *vec);
+/* Drop last element of VECP. This is like calling
+ * vect_erase(VEC, vect_size(VEC)-1, vect_size(VEC), DTOR, DATA); */
+void vect_popback(struct vect *vec,
+ void (*dtor)(void *emt, void *data), void *data);
+
+#define VECT_POPBACK(VECP, ELT_TYPE, DTOR, DATA) \
+ do \
+ VECT_ERASE((VECP), ELT_TYPE, \
+ vect_size(VECP) - 1, vect_size(VECP), \
+ DTOR, DATA); \
+ while (0)
+
+/* Drop elements START (inclusive) to END (non-inclusive) of VECP. If
+ * DTOR is non-NULL, it is called on each of the removed elements.
+ * DATA is passed verbatim to DTOR. */
+void vect_erase(struct vect *vec, size_t start, size_t end,
+ void (*dtor)(void *emt, void *data), void *data);
+
+#define VECT_ERASE(VECP, ELT_TYPE, START, END, DTOR, DATA) \
+ do { \
+ assert((VECP)->elt_size == sizeof(ELT_TYPE)); \
+ /* Check that DTOR is typed properly. */ \
+ void (*_dtor_callback)(ELT_TYPE *, void *) = DTOR; \
+ vect_erase((VECP), (START), (END), \
+ (void (*)(void *, void *))_dtor_callback, DATA); \
+ } while (0)
/* Copy element referenced by ELTP to the end of VEC. See
* vect_pushback for details. In addition, make a check whether VECP
@@ -140,11 +164,48 @@ void *vect_each(struct vect *vec, void *start_after,
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, \
+ ELT_TYPE *_start_after = (START_AFTER); \
+ (ELT_TYPE *)vect_each((VECP), _start_after, \
(enum callback_status \
(*)(void *, void *))_cb, \
DATA); \
})
+/* Iterate through vector VEC. See callback.h for notes on iteration
+ * interfaces. */
+const void *vect_each_cst(const struct vect *vec, const void *start_after,
+ enum callback_status (*cb)(const void *, void *),
+ void *data);
+
+#define VECT_EACH_CST(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)(const ELT_TYPE *, void *) = CB; \
+ const ELT_TYPE *start_after = (START_AFTER); \
+ (const ELT_TYPE *)vect_each_cst((VECP), start_after, \
+ (enum callback_status \
+ (*)(const void *, \
+ void *))_cb, \
+ DATA); \
+ })
+
+/* Call qsort on elements of VECT, with COMPAR as a comparison
+ * function. */
+void vect_qsort(struct vect *vec, int (*compar)(const void *, const void *));
+
+#define VECT_QSORT(VECP, ELT_TYPE, COMPAR) \
+ do { \
+ assert((VECP)->elt_size == sizeof(ELT_TYPE)); \
+ /* Check that CB is typed properly. */ \
+ int (*_compar)(const ELT_TYPE *, const ELT_TYPE *) = COMPAR; \
+ vect_qsort((VECP), \
+ (int (*)(const void *, const void *))_compar); \
+ } while (0)
+
+
+/* A dtor which calls 'free' on elements of a vector. */
+void vect_dtor_string(char **key, void *data);
+
#endif /* VECT_H */