/* This software is licensed by the MIT License, see LICENSE file */ /* Copyright © 2022 Gregory Lirent */ #include "include.h" bool libcdsb_list_insert(list_t* x, ssize_t i, const void* v, vtype t, int ins) { ldir_t dir; lnode_t* c; if (i < 0) { i = ~i; dir = LD_PREV; } else dir = LD_NEXT; c = ldir_dir((lnode_t*)x, dir); while (i && !is_null(c)) { c = ldir_dir(c, dir); --i; } if (i && dir == LD_PREV) { c = x->first; } else if (i) return false; if (is_null(c)) { x->first = x->last = c = calloc(sizeof(*c), 1); } else if (ins) { lnode_t *v = malloc(sizeof(*v)); dir = (ins < 0) ? LD_PREV : LD_NEXT; ldir_dir(v, dir) = ldir_dir(c, dir); ldir_inv(v, dir) = c; c = v; if (!is_null(ldir_dir(c, dir))) { ldir_inv(ldir_dir(c, dir), dir) = c; } else ldir_inv((lnode_t*)x, dir) = c; ldir_dir(ldir_inv(c, dir), dir) = c; } else vnode_free(&c->node, c->type); c->node = vnode_create(v, t); c->type = t; return true; } bool libcdsb_list_attach(list_t* x, ssize_t i, const void* v, vtype t, int ins) { ldir_t dir; lnode_t* c; if (i < 0) { i = ~i; dir = LD_PREV; } else dir = LD_NEXT; c = ldir_dir((lnode_t*)x, dir); while (i && !is_null(c)) { c = ldir_dir(c, dir); --i; } if (i && dir == LD_PREV) { c = x->first; } else if (i) return false; if (is_null(c)) { x->first = x->last = c = calloc(sizeof(*c), 1); } else if (ins) { lnode_t *v = malloc(sizeof(*v)); dir = (ins < 0) ? LD_PREV : LD_NEXT; ldir_dir(v, dir) = ldir_dir(c, dir); ldir_inv(v, dir) = c; c = v; if (!is_null(ldir_dir(c, dir))) { ldir_inv(ldir_dir(c, dir), dir) = c; } else ldir_inv((lnode_t*)x, dir) = c; ldir_dir(ldir_inv(c, dir), dir) = c; } else vnode_free(&c->node, c->type); if (t < VTYPE_STRING) { c->node = vnode_create(v, t); } else if (sizeof(str_t) == sizeof(void*) && t == VTYPE_STRING) { c->node = *(char**)v; } else { c->node = malloc(vtype_size(t)); memcpy(c->node, v, vtype_size(t)); } c->type = t; return true; }