/* This software is licensed by the MIT License, see LICENSE file */ /* Copyright © 2022 Gregory Lirent */ #include "include.h" static void init_first(list_t* x, vnode_t v, vtype t) { lnode_t* node = malloc(sizeof(*node)); node->next = nullptr; node->prev = nullptr; node->node = v; node->type = t; x->first = node; x->last = node; } static void push_next(list_t* x, vnode_t v, vtype t) { lnode_t* node = malloc(sizeof(*node)); node->next = nullptr; node->prev = x->last; node->node = v; node->type = t; x->last->next = node; x->last = node; } /*#####################################################################################################################*/ list_t list_copy(const list_t* s) { list_t x; lnode_t* c; c = s->first; memset(&x, 0, sizeof(x)); if (is_null(c)) return x; init_first(&x, vnode_duplicate(&c->node, c->type), c->type); while (!is_null(c = c->next)) { push_next(&x, vnode_duplicate(&c->node, c->type), c->type); } return x; } list_t* list_duplicate(const list_t* s) { list_t* x; lnode_t* c; c = s->first; x = calloc(sizeof(*x), 1); if (is_null(c)) return x; init_first(x, vnode_duplicate(&c->node, c->type), c->type); while (!is_null(c = c->next)) { push_next(x, vnode_duplicate(&c->node, c->type), c->type); } return x; } void list_copy_init(list_t* x, const list_t* s) { lnode_t* c; c = s->first; memset(x, 0, sizeof(*x)); if (is_null(c)) return; init_first(x, vnode_duplicate(&c->node, c->type), c->type); while (!is_null(c = c->next)) { push_next(x, vnode_duplicate(&c->node, c->type), c->type); } } void list_extend(list_t* x, const list_t* s) { lnode_t* c; c = s->first; if (is_null(c)) return; if (is_null(x->first)) { init_first(x, vnode_duplicate(&c->node, c->type), c->type); c = c->next; if (is_null(c)) return; } do { 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) { 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 s->first = e->next; if (e->next) { e->next->prev = c->prev; } else s->last = c->prev; (x->first = c)->prev = nullptr; (x->last = e)->next = nullptr; } return r; }