diff --git a/src/c-list/.github/workflows/ci.yml b/src/c-list/.github/workflows/ci.yml
index 76a41592d0..e07f3118d7 100644
--- a/src/c-list/.github/workflows/ci.yml
+++ b/src/c-list/.github/workflows/ci.yml
@@ -9,23 +9,19 @@ on:
jobs:
ci:
name: CI with Default Configuration
- runs-on: ubuntu-latest
-
- steps:
- - name: Fetch Sources
- uses: actions/checkout@v2
- - name: Run through C-Util CI
- uses: c-util/automation/src/ci-c-util@v1
- with:
- m32: 1
- valgrind: 1
+ uses: bus1/cabuild/.github/workflows/ci-c-util.yml@v1
+ with:
+ cabuild_ref: "v1"
+ m32: true
+ matrixmode: true
+ valgrind: true
ci-msvc:
name: CI with MSVC
runs-on: ${{ matrix.os }}
strategy:
matrix:
- os: [windows-2016, windows-latest]
+ os: [windows-2019, windows-latest]
steps:
- name: Fetch Sources
diff --git a/src/c-list/AUTHORS b/src/c-list/AUTHORS
index 439473ced6..76dea8729d 100644
--- a/src/c-list/AUTHORS
+++ b/src/c-list/AUTHORS
@@ -30,11 +30,12 @@ AUTHORS-LGPL:
along with this program; If not, see .
COPYRIGHT: (ordered alphabetically)
- Copyright (C) 2015-2019 Red Hat, Inc.
+ Copyright (C) 2015-2022 Red Hat, Inc.
AUTHORS: (ordered alphabetically)
Danilo Horta
David Rheinsberg
Lucas De Marchi
+ Michele Dionisio
Thomas Haller
Tom Gundersen
diff --git a/src/c-list/NEWS.md b/src/c-list/NEWS.md
index 0404389597..02d2c9a5ca 100644
--- a/src/c-list/NEWS.md
+++ b/src/c-list/NEWS.md
@@ -1,5 +1,18 @@
# c-list - Circular Intrusive Double Linked List Collection
+## CHANGES WITH 4:
+
+ * The minimum required meson version is now 0.60.0.
+
+ * New function c_list_split() is added. It reverses c_list_splice()
+ and thus allows to split a list in half.
+
+ * TBD
+
+ Contributions from: David Rheinsberg
+
+ - TBD, YYYY-MM-DD
+
## CHANGES WITH 3:
* API break: The c_list_loop_*() symbols were removed, since we saw
diff --git a/src/c-list/README.md b/src/c-list/README.md
index d14198999f..a2e47528ed 100644
--- a/src/c-list/README.md
+++ b/src/c-list/README.md
@@ -20,7 +20,7 @@ The requirements for this project are:
At build-time, the following software is required:
- * `meson >= 0.41`
+ * `meson >= 0.60`
* `pkg-config >= 0.29`
### Build
diff --git a/src/c-list/meson.build b/src/c-list/meson.build
index 21bb784f1c..1776b105f2 100644
--- a/src/c-list/meson.build
+++ b/src/c-list/meson.build
@@ -1,15 +1,46 @@
project(
'c-list',
'c',
- version: '3',
- license: 'Apache',
default_options: [
'c_std=c99',
],
+ license: 'Apache',
+ meson_version: '>=0.60.0',
+ version: '3.0.0',
)
+major = meson.project_version().split('.')[0]
project_description = 'Circular Intrusive Double Linked List Collection'
-add_project_arguments('-D_GNU_SOURCE', language: 'c')
mod_pkgconfig = import('pkgconfig')
+# See c-stdaux for details on these. We do not have c-stdaux as dependency, so
+# we keep a duplicated set here, reduced to the minimum.
+cflags = meson.get_compiler('c').get_supported_arguments(
+ '-D_GNU_SOURCE',
+
+ '-Wno-gnu-alignof-expression',
+ '-Wno-maybe-uninitialized',
+ '-Wno-unknown-warning-option',
+ '-Wno-unused-parameter',
+
+ '-Wno-error=type-limits',
+ '-Wno-error=missing-field-initializers',
+
+ '-Wdate-time',
+ '-Wdeclaration-after-statement',
+ '-Wlogical-op',
+ '-Wmissing-include-dirs',
+ '-Wmissing-noreturn',
+ '-Wnested-externs',
+ '-Wredundant-decls',
+ '-Wshadow',
+ '-Wstrict-aliasing=3',
+ '-Wsuggest-attribute=noreturn',
+ '-Wundef',
+ '-Wwrite-strings',
+)
+add_project_arguments(cflags, language: 'c')
+
subdir('src')
+
+meson.override_dependency('libclist-'+major, libclist_dep, static: true)
diff --git a/src/c-list/src/c-list.h b/src/c-list/src/c-list.h
index 69de0b31eb..711b54d630 100644
--- a/src/c-list/src/c-list.h
+++ b/src/c-list/src/c-list.h
@@ -259,6 +259,31 @@ static inline void c_list_splice(CList *target, CList *source) {
}
}
+/**
+ * c_list_split() - split one list in two
+ * @source: the list to split
+ * @where: new starting element of newlist
+ * @target: new list
+ *
+ * This splits @source in two. All elements following @where (including @where)
+ * are moved to @target, replacing any old list. If @where points to @source
+ * (i.e., the end of the list), @target will be empty.
+ */
+static inline void c_list_split(CList *source, CList *where, CList *target) {
+ if (where == source) {
+ *target = (CList)C_LIST_INIT(*target);
+ } else {
+ target->next = where;
+ target->prev = source->prev;
+
+ where->prev->next = source;
+ source->prev = where->prev;
+
+ where->prev = target;
+ target->prev->next = target;
+ }
+}
+
/**
* c_list_first() - return pointer to first element, or NULL if empty
* @list: list to operate on, or NULL
diff --git a/src/c-list/src/meson.build b/src/c-list/src/meson.build
index 0261ae0c2f..ec7f29d5f5 100644
--- a/src/c-list/src/meson.build
+++ b/src/c-list/src/meson.build
@@ -13,10 +13,10 @@ if not meson.is_subproject()
install_headers('c-list.h')
mod_pkgconfig.generate(
- version: meson.project_version(),
- name: 'libclist',
- filebase: 'libclist',
description: project_description,
+ filebase: 'libclist-'+major,
+ name: 'libclist',
+ version: meson.project_version(),
)
endif
diff --git a/src/c-list/src/test-api.c b/src/c-list/src/test-api.c
index bf760cf92f..864d198a65 100644
--- a/src/c-list/src/test-api.c
+++ b/src/c-list/src/test-api.c
@@ -17,7 +17,8 @@ typedef struct {
} Node;
static void test_api(void) {
- CList *list_iter, *list_safe, list = C_LIST_INIT(list);
+ CList *list_iter, *list_safe;
+ CList list = C_LIST_INIT(list), list2 = C_LIST_INIT(list2);
Node node = { .id = 0, .link = C_LIST_INIT(node.link) };
assert(c_list_init(&list) == &list);
@@ -68,7 +69,7 @@ static void test_api(void) {
c_list_unlink(&node.link);
assert(!c_list_is_linked(&node.link));
- /* swap / splice list operators */
+ /* swap / splice / split list operators */
c_list_swap(&list, &list);
assert(c_list_is_empty(&list));
@@ -76,6 +77,10 @@ static void test_api(void) {
c_list_splice(&list, &list);
assert(c_list_is_empty(&list));
+ c_list_split(&list, &list, &list2);
+ assert(c_list_is_empty(&list));
+ assert(c_list_is_empty(&list2));
+
/* direct/raw iterators */
c_list_for_each(list_iter, &list)
diff --git a/src/c-list/src/test-basic.c b/src/c-list/src/test-basic.c
index 06cccd852b..58ed863684 100644
--- a/src/c-list/src/test-basic.c
+++ b/src/c-list/src/test-basic.c
@@ -11,6 +11,18 @@
#include
#include "c-list.h"
+static void assert_list_integrity(CList *list) {
+ CList *iter;
+
+ iter = list;
+ do {
+ assert(iter->next->prev == iter);
+ assert(iter->prev->next == iter);
+
+ iter = iter->next;
+ } while (iter != list);
+}
+
static void test_iterators(void) {
CList *iter, *safe, a, b, list = C_LIST_INIT(list);
unsigned int i;
@@ -158,6 +170,85 @@ static void test_splice(void) {
assert(c_list_last(&target) == &e2);
}
+static void test_split(void) {
+ CList e1, e2;
+
+ /* split empty list */
+ {
+ CList source = C_LIST_INIT(source), target;
+
+ c_list_split(&source, &source, &target);
+ assert(c_list_is_empty(&source));
+ assert(c_list_is_empty(&target));
+ assert_list_integrity(&source);
+ assert_list_integrity(&target);
+ }
+
+ /* split 1-element list excluding the element */
+ {
+ CList source = C_LIST_INIT(source), target;
+
+ c_list_link_tail(&source, &e1);
+ c_list_split(&source, &source, &target);
+ assert(!c_list_is_empty(&source));
+ assert(c_list_is_empty(&target));
+ assert_list_integrity(&source);
+ assert_list_integrity(&target);
+ }
+
+ /* split 1-element list including the element */
+ {
+ CList source = C_LIST_INIT(source), target;
+
+ c_list_link_tail(&source, &e1);
+ c_list_split(&source, &e1, &target);
+ assert(c_list_is_empty(&source));
+ assert(!c_list_is_empty(&target));
+ assert_list_integrity(&source);
+ assert_list_integrity(&target);
+ }
+
+ /* split 2-element list excluding the elements */
+ {
+ CList source = C_LIST_INIT(source), target;
+
+ c_list_link_tail(&source, &e1);
+ c_list_link_tail(&source, &e2);
+ c_list_split(&source, &source, &target);
+ assert(!c_list_is_empty(&source));
+ assert(c_list_is_empty(&target));
+ assert_list_integrity(&source);
+ assert_list_integrity(&target);
+ }
+
+ /* split 2-element list including one element */
+ {
+ CList source = C_LIST_INIT(source), target;
+
+ c_list_link_tail(&source, &e1);
+ c_list_link_tail(&source, &e2);
+ c_list_split(&source, &e2, &target);
+ assert(!c_list_is_empty(&source));
+ assert(!c_list_is_empty(&target));
+ assert_list_integrity(&source);
+ assert_list_integrity(&target);
+ }
+
+ /* split 2-element list including both elements */
+ {
+ CList source = C_LIST_INIT(source), target;
+
+ c_list_link_tail(&source, &e1);
+ c_list_link_tail(&source, &e2);
+ c_list_split(&source, &e1, &target);
+ assert(c_list_is_empty(&source));
+ assert(!c_list_is_empty(&target));
+ assert_list_integrity(&source);
+ assert_list_integrity(&target);
+ }
+}
+
+
static void test_flush(void) {
CList e1 = C_LIST_INIT(e1), e2 = C_LIST_INIT(e2);
CList list1 = C_LIST_INIT(list1), list2 = C_LIST_INIT(list2);
@@ -220,6 +311,7 @@ int main(void) {
test_iterators();
test_swap();
test_splice();
+ test_split();
test_flush();
test_macros();
test_gnu();