Use va_arg for linking

This commit is contained in:
Alex D. 2021-08-14 18:15:28 +00:00
parent 53643eba88
commit b435f5cc55
Signed by: caskd
GPG Key ID: F92BA85F61F4C173
3 changed files with 32 additions and 34 deletions

View File

@ -1,3 +1,3 @@
VERSION = 1.3.0
VERSION = 1.4.0
PREFIX = /usr/local
CC = clang

54
llist.c
View File

@ -18,13 +18,13 @@
#include "llist.h"
#include <stdarg.h> // va_args
#include <stdint.h> // uintmax_t
#include <stdlib.h> // malloc() free()
static llist_err corelibs_llist_create(void*, void (*)(void*), llist_t**);
static llist_err corelibs_llist_link_duo(llist_t*, llist_t*);
static llist_err corelibs_llist_link_trio(llist_t*, llist_t*, llist_t*);
static llist_err corelibs_llist_link(uintmax_t cnt, ...);
static llist_err corelibs_llist_free_list(llist_t*);
static llist_err corelibs_llist_free_elem(llist_t*);
@ -45,7 +45,8 @@ struct llist_t {
};
enum { // Avoid collision in error numbers
CORELIBS_LLIST_ERR_UNDEF = -3,
CORELIBS_LLIST_ERR_MARGS = -4,
CORELIBS_LLIST_ERR_UNDEF,
CORELIBS_LLIST_ERR_NULL,
CORELIBS_LLIST_ERR_ALLOC,
CORELIBS_LLIST_ERR_UNK = 0,
@ -54,10 +55,7 @@ enum { // Avoid collision in error numbers
struct corelibs_llist_interface const llist = {
.create = corelibs_llist_create,
.link = {
.duo = corelibs_llist_link_duo,
.trio = corelibs_llist_link_trio,
},
.link = corelibs_llist_link,
.free = {
.list = corelibs_llist_free_list,
.elem = corelibs_llist_free_elem,
@ -79,6 +77,9 @@ struct corelibs_llist_interface const llist = {
.null = CORELIBS_LLIST_ERR_NULL,
.alloc = CORELIBS_LLIST_ERR_ALLOC,
},
.args = {
.mis = CORELIBS_LLIST_ERR_MARGS,
},
},
};
@ -148,37 +149,32 @@ ret:
}
static llist_err
corelibs_llist_link_duo(llist_t* a, llist_t* b)
corelibs_llist_link(uintmax_t cnt, ...)
{
llist_err err = CORELIBS_LLIST_ERR_OK;
if (a == NULL && b == NULL) {
err = CORELIBS_LLIST_ERR_NULL;
if (cnt <= 1) {
err = CORELIBS_LLIST_ERR_MARGS;
goto ret;
}
if (a != NULL) a->next = b;
if (b != NULL) b->prev = a;
ret:
return err;
}
va_list ap;
va_start(ap, cnt);
static llist_err
corelibs_llist_link_trio(llist_t* a, llist_t* b, llist_t* c)
{
llist_err err = CORELIBS_LLIST_ERR_OK;
uintmax_t ccnt = 0;
llist_t * a = NULL, *b = NULL;
while (ccnt < cnt) {
a = b;
b = va_arg(ap, llist_t*);
if (ccnt < 1) continue; // Fill at least first 2 slots
if (a == NULL && b == NULL && c == NULL) {
err = CORELIBS_LLIST_ERR_NULL;
goto ret;
if (a != NULL) a->next = b;
if (b != NULL) b->prev = a;
ccnt++;
}
if (a != NULL) a->next = b;
if (b != NULL) {
b->next = c;
b->prev = a;
}
if (c != NULL) c->prev = b;
va_end(ap);
ret:
return err;
}
@ -270,7 +266,7 @@ ret:
static void
corelibs_llist_remove(llist_t* e)
{
corelibs_llist_link_duo(e->prev, e->next);
corelibs_llist_link(2, e->prev, e->next);
if (e->free != NULL) e->free(e->cont);
free(e);
}

10
llist.h
View File

@ -16,6 +16,8 @@
* along with corelibs. If not, see <https://www.gnu.org/licenses/>.
*/
#include <stdint.h> // uintmax_t
#ifndef CORELIBS_GUARD_LLIST
#define CORELIBS_GUARD_LLIST
@ -24,10 +26,7 @@ typedef signed short int llist_err;
struct corelibs_llist_interface {
llist_err (*const create)(void* content, void (*const free_function)(void*), llist_t** save);
const struct {
llist_err (*const duo)(llist_t* element_a, llist_t* element_b);
llist_err (*const trio)(llist_t* element_a, llist_t* element_b, llist_t* element_c);
} link;
llist_err (*const link)(uintmax_t elements, ...);
const struct {
llist_err (*const list)(llist_t* element);
llist_err (*const elem)(llist_t* element);
@ -49,6 +48,9 @@ struct corelibs_llist_interface {
const llist_err null, // NULL address was passed
alloc; // Allocation failed
} mem;
const struct {
const llist_err mis; // Missing arguments / Not enough arguments
} args;
} err;
};
extern const struct corelibs_llist_interface llist;