about summary refs log tree commit diff
path: root/shared/nm-glib-aux/nm-c-list.h
diff options
context:
space:
mode:
Diffstat (limited to 'shared/nm-glib-aux/nm-c-list.h')
-rw-r--r--shared/nm-glib-aux/nm-c-list.h103
1 files changed, 85 insertions, 18 deletions
diff --git a/shared/nm-glib-aux/nm-c-list.h b/shared/nm-glib-aux/nm-c-list.h
index 5c73f574..7512730d 100644
--- a/shared/nm-glib-aux/nm-c-list.h
+++ b/shared/nm-glib-aux/nm-c-list.h
@@ -1,4 +1,3 @@
-/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
 /* NetworkManager -- Network link manager
  *
  * This library is free software; you can redistribute it and/or
@@ -33,6 +32,8 @@
 		_what && c_list_contains (list, &_what->member); \
 	})
 
+/*****************************************************************************/
+
 typedef struct {
 	CList lst;
 	void *data;
@@ -48,21 +49,34 @@ nm_c_list_elem_new_stale (void *data)
 	return elem;
 }
 
-static inline void *
-nm_c_list_elem_get (CList *lst)
+static inline gboolean
+nm_c_list_elem_free_full (NMCListElem *elem, GDestroyNotify free_fcn)
 {
-	if (!lst)
-		return NULL;
-	return c_list_entry (lst, NMCListElem, lst)->data;
+	if (!elem)
+		return FALSE;
+	c_list_unlink_stale (&elem->lst);
+	if (free_fcn)
+		free_fcn (elem->data);
+	g_slice_free (NMCListElem, elem);
+	return TRUE;
 }
 
-static inline void
+static inline gboolean
 nm_c_list_elem_free (NMCListElem *elem)
 {
-	if (elem) {
-		c_list_unlink_stale (&elem->lst);
-		g_slice_free (NMCListElem, elem);
-	}
+	return nm_c_list_elem_free_full (elem, NULL);
+}
+
+static inline void *
+nm_c_list_elem_free_steal (NMCListElem *elem)
+{
+	gpointer data;
+
+	if (!elem)
+		return NULL;
+	data = elem->data;
+	nm_c_list_elem_free_full (elem, NULL);
+	return data;
 }
 
 static inline void
@@ -70,22 +84,53 @@ nm_c_list_elem_free_all (CList *head, GDestroyNotify free_fcn)
 {
 	NMCListElem *elem;
 
-	while ((elem = c_list_first_entry (head, NMCListElem, lst))) {
-		if (free_fcn)
-			free_fcn (elem->data);
-		c_list_unlink_stale (&elem->lst);
-		g_slice_free (NMCListElem, elem);
+	while ((elem = c_list_first_entry (head, NMCListElem, lst)))
+		nm_c_list_elem_free_full (elem, free_fcn);
+}
+
+/**
+ * nm_c_list_elem_find_first:
+ * @head: the @CList head of a list containing #NMCListElem elements.
+ *   Note that the head is not itself part of the list.
+ * @needle: the needle pointer.
+ *
+ * Iterates the list and returns the first #NMCListElem with the matching @needle,
+ * using pointer equality.
+ *
+ * Returns: the found list element or %NULL if not found.
+ */
+static inline NMCListElem *
+nm_c_list_elem_find_first (CList *head, gconstpointer needle)
+{
+	NMCListElem *elem;
+
+	c_list_for_each_entry (elem, head, lst) {
+		if (elem->data == needle)
+			return elem;
 	}
+	return NULL;
 }
 
 /*****************************************************************************/
 
+/**
+ * nm_c_list_move_before:
+ * @lst: the list element to which @elem will be prepended.
+ * @elem: the list element to move.
+ *
+ * This unlinks @elem from the current list and linkes it before
+ * @lst. This is like c_list_link_before(), except that @elem must
+ * be initialized and linked. Note that @elem may be linked in @lst
+ * or in another list. In both cases it gets moved.
+ *
+ * Returns: %TRUE if there were any changes. %FALSE if elem was already
+ *   linked at the right place.
+ */
 static inline gboolean
 nm_c_list_move_before (CList *lst, CList *elem)
 {
 	nm_assert (lst);
 	nm_assert (elem);
-	nm_assert (c_list_contains (lst, elem));
 
 	if (   lst != elem
 	    && lst->prev != elem) {
@@ -97,12 +142,24 @@ nm_c_list_move_before (CList *lst, CList *elem)
 }
 #define nm_c_list_move_tail(lst, elem) nm_c_list_move_before (lst, elem)
 
+/**
+ * nm_c_list_move_after:
+ * @lst: the list element to which @elem will be prepended.
+ * @elem: the list element to move.
+ *
+ * This unlinks @elem from the current list and linkes it after
+ * @lst. This is like c_list_link_after(), except that @elem must
+ * be initialized and linked. Note that @elem may be linked in @lst
+ * or in another list. In both cases it gets moved.
+ *
+ * Returns: %TRUE if there were any changes. %FALSE if elem was already
+ *   linked at the right place.
+ */
 static inline gboolean
 nm_c_list_move_after (CList *lst, CList *elem)
 {
 	nm_assert (lst);
 	nm_assert (elem);
-	nm_assert (c_list_contains (lst, elem));
 
 	if (   lst != elem
 	    && lst->next != elem) {
@@ -114,4 +171,14 @@ nm_c_list_move_after (CList *lst, CList *elem)
 }
 #define nm_c_list_move_front(lst, elem) nm_c_list_move_after (lst, elem)
 
+#define nm_c_list_free_all(lst, type, member, destroy_fcn) \
+	G_STMT_START { \
+		CList *const _lst = (lst); \
+		type *_elem; \
+		\
+		while ((_elem = c_list_first_entry (_lst, type, member))) { \
+			destroy_fcn (_elem); \
+		} \
+	} G_STMT_END
+
 #endif /* __NM_C_LIST_H__ */