diff --git a/include/list.h b/include/list.h index eda1488..a88fc19 100644 --- a/include/list.h +++ b/include/list.h @@ -12,6 +12,8 @@ extern void list_init(vtype_list* x); extern void list_extend(vtype_list* x, const vtype_list* s); +extern size_t list_slice(vtype_list* x, vtype_list* src, ssize_t index, size_t count, _Bool cut) LIBCDSB_nt__ LIBCDSB_nn12__; + extern void list_sort(vtype_list* x); extern void list_reverse(vtype_list* x); diff --git a/src/list/copy.c b/src/list/copy.c index fb714ae..c9839c6 100644 --- a/src/list/copy.c +++ b/src/list/copy.c @@ -107,3 +107,80 @@ void list_extend(list_t* x, const list_t* s) { push_next(x, vnode_duplicate(&c->node, c->type), c->type); } while (!is_null(c = c->next)); } + + + +size_t list_slice(list_t* x, list_t* s, ssize_t i, size_t n, _Bool cut) { + + ldir_t dir; + lnode_t* c; + lnode_t* e; + size_t r; + + r = n; + + if (!n || is_null(s->first)) { + memset(x, 0, sizeof(*x)); + return 0; + } + + if (i < 0) { + c = s->last; + e = s->last; + i = ~i; + + while (i && !is_null(c)) { + c = c->prev; + --i; + if (!n) { e = e->prev; } + else --n; + } + + if (is_null(c)) c = x->first; + } else { + c = s->first; + + while (i && !is_null(c)) { + c = c->next; + --i; + } + + e = c; + + while (n && !is_null(e)) { + e = e->next; + --n; + } + + if (is_null(e)) e = x->last; + } + + if (is_null(c)) return 0; + else r -= n; + + if (!cut) { + init_first(x, vnode_duplicate(&c->node, c->type), c->type); + + while ((c = c->next) != e) { + push_next(x, vnode_duplicate(&c->node, c->type), c->type); + } + + push_next(x, vnode_duplicate(&e->node, e->type), e->type); + } else { + if (c->prev) { + c->prev->next = e->next; + } else x->first = e->next; + + if (e->next) { + e->next->prev = c->prev; + } else s->last = c->prev; + + e->next = nullptr; + c->prev = nullptr; + + x->first = c; + x->last = e; + } + + return r; +} diff --git a/src/list/extra.c b/src/list/extra.c index b51ee54..8b578c7 100644 --- a/src/list/extra.c +++ b/src/list/extra.c @@ -59,14 +59,15 @@ ssize_t libcdsb_list_get(val_t* x, list_t* s, ssize_t i, _Bool cut) { /*#####################################################################################################################*/ ssize_t libcdsb_list_find(val_t* x, list_t* s, const void* v, vtype t, _Bool r, _Bool cut) { - ldir_t dir = r ? LD_PREV : LD_NEXT; + ldir_t dir; lnode_t* c; ssize_t i; int cmp; - c = ldir_dir((lnode_t*)s, dir); - i = 0; + dir = r ? LD_PREV : LD_NEXT; + c = ldir_dir((lnode_t*)s, dir); + i = 0; if (!is_null(x)) memset(x, 0, sizeof(*x)); @@ -178,7 +179,7 @@ int libcdsb_list_foreach(vtype_list* x, void* data, list_foreach_callback callba break; n = c->next; - + if (flush) { vnode_free(&c->node, c->type); free(c);