typedef void (*apply_cb)(elem_value value, void *user_data);
/**
+ * @brief Apply callback to list element, with return
+ * @param value list element value
+ * @param user_data pointer to user data to be forwarded to callback
+ * @return 0 if everything was ok, nonzero otherwise
+ */
+typedef int (*apply_ret_cb)(elem_value value, void *user_data);
+
+/**
* @brief Map callback to list element
* @param value list element value
* @param user_data pointer to user data to be forwarded to callback
void list_foreach(list_head head, void *user_data, apply_cb apply);
/**
+ * @brief Call given callback for all elements in the list
+ * @param[in] head list head
+ * @param[in] user_data pointer to user data to be forwarded to callback
+ * @param[in] apply callback to call for each element in the list
+ * @return The first non-zero return value from the callback, or zero
+ */
+int list_foreach_ret(list_head head, void *user_data, apply_ret_cb apply);
+
+/**
* @brief Create a new list by looping over a given one
* @param[in] head list head
* @param[in] user_data pointer to user data to be forwarded to the callbacks
apply(elem->value, user_data);
}
+int list_foreach_ret(list_head head, void *user_data, apply_ret_cb apply)
+{
+ assert(apply);
+
+ struct list_elem *elem;
+ for (elem = head; elem; elem = elem->next) {
+ int r = apply(elem->value, user_data);
+ if (r)
+ return r;
+ }
+
+ return 0;
+}
+
list_head list_map(list_head head, void *user_data, map_cb map, apply_cb clear)
{
assert(map);
#include "test_ptrs_list_wrap.c"
+int ret_cb(void *element, void *userdata)
+{
+ if (element == (void *) 0x7AC5A71F)
+ return 789;
+ if (element == (void *) 0xBADF00D)
+ return 321;
+ return 0;
+}
+
+void test_foreach_ret()
+{
+ list_head head = NULL;
+
+ // Some kosher elements, no problems anticipated.
+ list_add(&head, (void *) 0xC0C0A);
+ list_add(&head, (void *) 0xC00CEE);
+ list_add(&head, (void *) 0xC0FFEE);
+ assert(list_foreach_ret(head, NULL, ret_cb) == 0);
+
+ // Add something inedible.
+ list_add(&head, (void *) 0xBADF00D);
+ assert(list_foreach_ret(head, NULL, ret_cb) == 321);
+
+ /* Iteration is in order; insertion happens at the front,
+ * so the newly added element is now returned. */
+ list_add(&head, (void *) 0x7AC5A71F);
+ assert(list_foreach_ret(head, NULL, ret_cb) == 789);
+
+ list_remove(&head, (void *) 0x7AC5A71F);
+ assert(list_foreach_ret(head, NULL, ret_cb) == 321);
+
+ list_remove(&head, (void *) 0xBADF00D);
+ assert(list_foreach_ret(head, NULL, ret_cb) == 0);
+
+ list_clear(&head);
+}
+
int main(void)
{
list_head head = NULL;
for (size_t i = 0; i < NELEMS(pointers_to_free); ++i)
assert(pointers_to_free[i] == NULL);
+ // An empty list has no chance to fail.
+ assert(list_foreach_ret(head, NULL, ret_cb) == 0);
+
+ test_foreach_ret();
+
return 0;
}