c-list: re-import git-subtree for 'src/c-list'

git subtree pull --prefix src/c-list git@github.com:c-util/c-list.git main --squash
This commit is contained in:
Thomas Haller 2022-05-06 09:51:53 +02:00
commit 192864ed3d
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
9 changed files with 184 additions and 21 deletions

View file

@ -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

View file

@ -30,11 +30,12 @@ AUTHORS-LGPL:
along with this program; If not, see <http://www.gnu.org/licenses/>.
COPYRIGHT: (ordered alphabetically)
Copyright (C) 2015-2019 Red Hat, Inc.
Copyright (C) 2015-2022 Red Hat, Inc.
AUTHORS: (ordered alphabetically)
Danilo Horta <danilo.horta@pm.me>
David Rheinsberg <david.rheinsberg@gmail.com>
Lucas De Marchi <lucas.de.marchi@gmail.com>
Michele Dionisio
Thomas Haller <thaller@redhat.com>
Tom Gundersen <teg@jklm.no>

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -11,6 +11,18 @@
#include <string.h>
#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();