about summary refs log tree commit diff
path: root/src/libnm-std-aux/c-list-util.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2022-10-04 00:56:46 +0200
committerMichael Biebl <biebl@debian.org>2022-10-04 00:56:46 +0200
commit3612e6355f3f40d264ec4657547761069baa5430 (patch)
tree768e4f5b37b66f540dd7030aa2eaff2ac7bb0168 /src/libnm-std-aux/c-list-util.c
parent7e9f00a3be8f65535e6620b344443ec4d403212b (diff)
parent6f7fcde10e47d8af865af336becf1fd8a446e62e (diff)
Merge tag 'debian/1.40.0-1' into debian/bullseye-backports
network-manager Debian release 1.40.0-1
Diffstat (limited to 'src/libnm-std-aux/c-list-util.c')
-rw-r--r--src/libnm-std-aux/c-list-util.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/libnm-std-aux/c-list-util.c b/src/libnm-std-aux/c-list-util.c
index d16bd6b7..12cd5f0f 100644
--- a/src/libnm-std-aux/c-list-util.c
+++ b/src/libnm-std-aux/c-list-util.c
@@ -182,3 +182,77 @@ c_list_sort(CList *head, CListSortCmp cmp, const void *user_data)
         c_list_relink(head);
     }
 }
+
+/*****************************************************************************/
+
+CList *
+c_list_first_unsorted(CList *list, int ascending, CListSortCmp cmp, const void *user_data)
+{
+    CList *iter_prev = NULL;
+    CList *iter;
+    int    c;
+
+    /* Returns the first element with the wrong sort order,
+     * or NULL, if they are all sorted. */
+
+    c_list_for_each (iter, list) {
+        if (iter_prev) {
+            c = cmp(iter_prev, iter, user_data);
+            if (ascending) {
+                if (c > 0)
+                    return iter;
+            } else {
+                if (c < 0)
+                    return iter;
+            }
+        }
+        iter_prev = iter;
+    }
+
+    return NULL;
+}
+
+void
+c_list_insert_sorted(CList       *list,
+                     CList       *elem,
+                     int          ascending,
+                     int          append_equal,
+                     CListSortCmp cmp,
+                     const void  *user_data)
+{
+    CList *iter;
+
+    /* We iterate the list front-to-end, and insert @elem according
+     * to the sort order @cmp. If @append_equal is TRUE, we will
+     * skip over equal elements and append afterwards. */
+    c_list_for_each (iter, list) {
+        int c;
+
+        c = cmp(iter, elem, user_data);
+
+        if (ascending) {
+            if (c < 0)
+                continue;
+            if (c > 0 || !append_equal)
+                goto out;
+        } else {
+            if (c > 0)
+                continue;
+            if (c < 0 || !append_equal)
+                goto out;
+        }
+
+        for (iter = iter->next; iter != list; iter = iter->next) {
+            c = cmp(iter, elem, user_data);
+            if (c != 0) {
+                /* We'd expect that the list is sorted, so @c should be
+                 * greater than 0. But don't enforce that. */
+                goto out;
+            }
+        }
+        goto out;
+    }
+
+out:
+    c_list_link_before(iter, elem);
+}