From 106825f7c5ee24c16ad68bc574b52a5c2cc074c5 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 6 May 2022 10:02:08 +0200 Subject: [PATCH] Squashed 'src/c-list/' changes from a0970f12f1f4..b86ba656ac22 b86ba656ac22 c-list: add c_list_split() 76900e4e3625 build: align with new c-util style git-subtree-dir: src/c-list git-subtree-split: b86ba656ac22b00fe785b2f058123e807f97c109 --- .github/workflows/ci.yml | 18 +++----- AUTHORS | 3 +- NEWS.md | 13 ++++++ README.md | 2 +- meson.build | 37 ++++++++++++++-- src/c-list.h | 25 +++++++++++ src/meson.build | 6 +-- src/test-api.c | 9 +++- src/test-basic.c | 92 ++++++++++++++++++++++++++++++++++++++++ 9 files changed, 184 insertions(+), 21 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 76a41592d0..e07f3118d7 100644 --- a/.github/workflows/ci.yml +++ b/.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/AUTHORS b/AUTHORS index 439473ced6..76dea8729d 100644 --- a/AUTHORS +++ b/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/NEWS.md b/NEWS.md index 0404389597..02d2c9a5ca 100644 --- a/NEWS.md +++ b/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/README.md b/README.md index d14198999f..a2e47528ed 100644 --- a/README.md +++ b/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/meson.build b/meson.build index 21bb784f1c..1776b105f2 100644 --- a/meson.build +++ b/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.h b/src/c-list.h index 69de0b31eb..711b54d630 100644 --- a/src/c-list.h +++ b/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/meson.build b/src/meson.build index 0261ae0c2f..ec7f29d5f5 100644 --- a/src/meson.build +++ b/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/test-api.c b/src/test-api.c index bf760cf92f..864d198a65 100644 --- a/src/test-api.c +++ b/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/test-basic.c b/src/test-basic.c index 06cccd852b..58ed863684 100644 --- a/src/test-basic.c +++ b/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();