libdvec-c

C memory vector library
git clone https://git.sinitax.com/sinitax/libdvec-c
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

commit 6eb0bdedd1078cf32bc0b54047bfb6e6c72f85d5
parent 8892e68e27576b4601da16173e2b82665a7fcdeb
Author: Louis Burda <quent.burda@gmail.com>
Date:   Mon, 13 Mar 2023 19:40:53 +0100

Simplify by removing HANDLE_ERR and forwarding errno to caller

Diffstat:
MMakefile | 25+++++++++----------------
Minclude/vec.h | 74++++++++++++++------------------------------------------------------------
Mlibvec.abi | 2++
Mlibvec.lds | 4+++-
Msrc/test.c | 12+++++++++---
Msrc/vec.c | 101++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
6 files changed, 101 insertions(+), 117 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,19 +1,11 @@ PREFIX ?= /usr/local LIBDIR ?= /lib -INCLUDEDIR ?= /include +INCLDIR ?= /include CFLAGS = -I include -Wno-prototype -Wunused-function -Wunused-variable -ifeq "$(LIBVEC_DEBUG)" "1" -CFLAGS += -g -endif - -ifeq "$(LIBVEC_ASSERT)" "1" -CFLAGS += -DLIBVEC_ASSERT_ENABLE=1 -endif - -ifeq "$(LIBVEC_HANDLE_ERR)" "1" -CFLAGS += -DLIBVEC_HANDLE_ERRS=1 +ifeq "$(DEBUG)" "1" +CFLAGS += -g -DLIBVEC_CHECK_ENABLE=1 endif all: build/libvec.so build/libvec.a build/test @@ -24,24 +16,25 @@ clean: build: mkdir build -build/libvec.a: src/vec.c include/vec.h | build +build/libvec.a: src/vec.c include/vec.h libvec.abi | build $(CC) -o build/tmp.o src/vec.c $(CFLAGS) -r objcopy --keep-global-symbols=libvec.abi build/tmp.o build/fixed.o ar rcs $@ build/fixed.o -build/libvec.so: src/vec.c include/vec.h | build - $(CC) -o $@ src/vec.c -fPIC $(CFLAGS) -shared -Wl,-version-script libvec.lds +build/libvec.so: src/vec.c include/vec.h libvec.lds | build + $(CC) -o $@ src/vec.c -fPIC $(CFLAGS) \ + -shared -Wl,-version-script libvec.lds build/test: src/test.c build/libvec.a $(CC) -o $@ $^ $(CFLAGS) install: - install -m644 include/vec.h -t "$(DESTDIR)$(PREFIX)$(INCLUDEDIR)" + install -m644 include/vec.h -t "$(DESTDIR)$(PREFIX)$(INCLDIR)" install -m755 build/libvec.so -t "$(DESTDIR)$(PREFIX)$(LIBDIR)" install -m755 build/libvec.a -t "$(DESTDIR)$(PREFIX)$(LIBDIR)" uninstall: - rm -f "$(DESTDIR)$(PREFIX)$(INCLUDEDIR)/vec.h" + rm -f "$(DESTDIR)$(PREFIX)$(INCLDIR)/vec.h" rm -f "$(DESTDIR)$(PREFIX)$(LIBDIR)/libvec.so" rm -f "$(DESTDIR)$(PREFIX)$(LIBDIR)/libvec.a" diff --git a/include/vec.h b/include/vec.h @@ -1,47 +1,8 @@ #pragma once #include <stdbool.h> -#include <stdio.h> #include <stdlib.h> -#ifdef LIBVEC_ASSERT_ENABLE - -#include <stdio.h> - -#define LIBVEC_ASSERT(x) libvec_assert((x), __FILE__, __LINE__, #x) - -static inline void libvec_assert(int cond, - const char *file, int line, const char *condstr) -{ - if (cond) return; - - fprintf(stderr, "libvec: Assertion failed at %s:%i (%s)\n", - file, line, condstr); - abort(); -} - -#else -#define LIBVEC_ASSERT(x) -#endif - -#ifdef LIBVEC_HANDLE_ERRS - -#include <errno.h> -#include <stdio.h> - -#define LIBVEC_HANDLE_ERR(x) libvec_err(__FILE__, __LINE__, x) - -static inline void libvec_err(const char *file, int line, const char *info) -{ - fprintf(stderr, "libvec: %s at %s:%i: %s\n", - info, file, line, strerror(errno)); - exit(1); -} - -#else -#define LIBVEC_HANDLE_ERR(x) -#endif - struct vec { size_t dsize; size_t len, cap; @@ -49,48 +10,46 @@ struct vec { void *data; }; -bool vec_init(struct vec *vec, size_t dsize, size_t cap); +int vec_init(struct vec *vec, size_t dsize, size_t cap); void vec_deinit(struct vec *vec); struct vec *vec_alloc(size_t dsize, size_t cap); void vec_free(struct vec *vec); void vec_clear(struct vec *vec); -bool vec_resize(struct vec *vec, size_t cap); -bool vec_shrink(struct vec *vec); +int vec_resize(struct vec *vec, size_t cap); +int vec_shrink(struct vec *vec); -bool vec_reserve(struct vec *vec, size_t index, size_t count); +int vec_reserve(struct vec *vec, size_t index, size_t count); void vec_remove(struct vec *vec, size_t index, size_t count); void vec_replace(struct vec *vec, size_t index, const void *data, size_t count); bool vec_iter_fwd(struct vec *vec, void **p); bool vec_iter_bwd(struct vec *vec, void **p); -static inline void *vec_at(struct vec *vec, size_t index) -{ - LIBVEC_ASSERT(vec != NULL && index < vec->len); +extern int libvec_errno; +static inline void * +vec_at(struct vec *vec, size_t index) +{ return vec->data + index * vec->dsize; } -static inline void *vec_front(struct vec *vec) +static inline void * +vec_front(struct vec *vec) { - LIBVEC_ASSERT(vec != NULL); - return vec->data; } -static inline void *vec_back(struct vec *vec) +static inline void * +vec_back(struct vec *vec) { - LIBVEC_ASSERT(vec != NULL && vec->len > 0); - return vec->data + (vec->len - 1) * vec->dsize; } -static inline bool vec_empty(struct vec *vec) +static inline bool +vec_empty(struct vec *vec) { - LIBVEC_ASSERT(vec != NULL); - return !vec->len; } @@ -98,7 +57,6 @@ static inline void * vec_alloc_slots(struct vec *vec, size_t count) { vec_reserve(vec, vec->len, count); - return vec->data + (vec->len - count) * vec->dsize; } @@ -111,10 +69,6 @@ vec_alloc_slot(struct vec *vec) static inline void vec_free_slots(struct vec *vec, void *slot, size_t count) { - LIBVEC_ASSERT(vec != NULL && slot >= vec->data - && slot < vec->data + vec->len * vec->dsize - && (slot - vec->data) % vec->dsize == 0); - vec_remove(vec, (slot - vec->data) / vec->dsize, count); } diff --git a/libvec.abi b/libvec.abi @@ -1,3 +1,5 @@ +libvec_errno + vec_init vec_deinit diff --git a/libvec.lds b/libvec.lds @@ -1,5 +1,7 @@ -LIBVEC_1.1 { +LIBVEC_1.2 { global: + libvec_errno; + vec_init; vec_deinit; diff --git a/src/test.c b/src/test.c @@ -1,19 +1,25 @@ #include "vec.h" -#include <stdlib.h> +#include <err.h> #include <stdio.h> #include <string.h> +#include <stdlib.h> + +#define LIBVEC_ERR() errx(1, "test: libvec: %s", strerror(libvec_errno)) int main(int argc, const char **argv) { struct vec vec; - int i, *val; + int i, ret; + int *val; - vec_init(&vec, sizeof(int), 10); + ret = vec_init(&vec, sizeof(int), 10); + if (ret) LIBVEC_ERR(); for (i = 1; i < argc; i++) { val = vec_alloc_slot(&vec); + if (!val) LIBVEC_ERR(); *val = atoi(argv[i]); } diff --git a/src/vec.c b/src/vec.c @@ -1,15 +1,32 @@ #include "vec.h" #include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <stdarg.h> #include <string.h> +#include <stdio.h> +#include <stdlib.h> -bool +#ifdef LIBVEC_CHECK_ENABLE +#define LIBVEC_CHECK(x) libvec_assert((x), __FILE__, __LINE__, #x) +#else +#define LIBVEC_CHECK(x) +#endif + +int libvec_errno = 0; + +static inline void +libvec_assert(int cond, const char *file, int line, const char *condstr) +{ + if (cond) return; + + fprintf(stderr, "libvec: Assertion failed at %s:%i (%s)\n", + file, line, condstr); + abort(); +} + +int vec_init(struct vec *vec, size_t dsize, size_t cap) { - LIBVEC_ASSERT(vec != NULL && dsize > 0 && cap >= 0); + LIBVEC_CHECK(vec != NULL && dsize > 0 && cap >= 0); vec->dsize = dsize; vec->cap = cap; @@ -19,18 +36,18 @@ vec_init(struct vec *vec, size_t dsize, size_t cap) if (vec->cap) { vec->data = calloc(cap, dsize); if (!vec->data) { - LIBVEC_HANDLE_ERR("calloc"); - return false; + libvec_errno = errno; + return libvec_errno; } } - return true; + return 0; } void vec_deinit(struct vec *vec) { - LIBVEC_ASSERT(vec != NULL); + LIBVEC_CHECK(vec != NULL); free(vec->data); } @@ -40,11 +57,11 @@ vec_alloc(size_t dsize, size_t cap) { struct vec *vec; - LIBVEC_ASSERT(dsize > 0 && cap > 0); + LIBVEC_CHECK(dsize > 0 && cap > 0); vec = malloc(sizeof(struct vec)); if (!vec) { - LIBVEC_HANDLE_ERR("malloc"); + libvec_errno = errno; return NULL; } @@ -59,7 +76,7 @@ vec_alloc(size_t dsize, size_t cap) void vec_free(struct vec *vec) { - LIBVEC_ASSERT(vec != NULL); + LIBVEC_CHECK(vec != NULL); vec_deinit(vec); free(vec); @@ -68,30 +85,35 @@ vec_free(struct vec *vec) void vec_clear(struct vec *vec) { - LIBVEC_ASSERT(vec != NULL); + LIBVEC_CHECK(vec != NULL); vec->len = 0; } -bool +int vec_resize(struct vec *vec, size_t cap) { - LIBVEC_ASSERT(vec != NULL && cap != 0 && vec->len <= cap); + void *alloc; + + LIBVEC_CHECK(vec != NULL && cap != 0 && vec->len <= cap); vec->cap = cap; - vec->data = realloc(vec->data, vec->cap * vec->dsize); - if (!vec->data) { - LIBVEC_HANDLE_ERR("realloc"); - return false; + alloc = realloc(vec->data, vec->cap * vec->dsize); + if (!alloc) { + libvec_errno = errno; + return libvec_errno; } + vec->data = alloc; - return true; + return 0; } -bool +int vec_shrink(struct vec *vec) { - LIBVEC_ASSERT(vec != NULL); + void *alloc; + + LIBVEC_CHECK(vec != NULL); if (!vec->len) { vec->cap = 1; @@ -99,29 +121,33 @@ vec_shrink(struct vec *vec) vec->cap = vec->len; } - vec->data = realloc(vec->data, vec->cap * vec->dsize); - if (!vec->data) { - LIBVEC_HANDLE_ERR("realloc"); - return false; + alloc = realloc(vec->data, vec->cap * vec->dsize); + if (!alloc) { + libvec_errno = errno; + return libvec_errno; } + vec->data = alloc; - return true; + return 0; } -bool +int vec_reserve(struct vec *vec, size_t index, size_t len) { - LIBVEC_ASSERT(vec != NULL && index <= vec->len); + void *alloc; + + LIBVEC_CHECK(vec != NULL && index <= vec->len); if (vec->len + len > vec->cap) { vec->cap *= 2; if (vec->len + len > vec->cap) vec->cap = vec->len + len; - vec->data = realloc(vec->data, vec->cap * vec->dsize); - if (!vec->data) { - LIBVEC_HANDLE_ERR("realloc"); - return false; + alloc = realloc(vec->data, vec->cap * vec->dsize); + if (!alloc) { + libvec_errno = errno; + return errno; } + vec->data = alloc; } if (index < vec->len) { @@ -138,7 +164,8 @@ vec_reserve(struct vec *vec, size_t index, size_t len) void vec_remove(struct vec *vec, size_t index, size_t count) { - LIBVEC_ASSERT(vec != NULL && count >= vec->len && index + count <= vec->len); + LIBVEC_CHECK(vec != NULL && count >= vec->len + && index + count <= vec->len); if (index + count < vec->len) { memmove(vec->data + index * vec->dsize, @@ -152,7 +179,7 @@ vec_remove(struct vec *vec, size_t index, size_t count) void vec_replace(struct vec *vec, size_t index, const void *data, size_t count) { - LIBVEC_ASSERT(vec != NULL && data != NULL && index + count < vec->len); + LIBVEC_CHECK(vec != NULL && data != NULL && index + count < vec->len); memcpy(vec->data + index * vec->dsize, data, count * vec->dsize); } @@ -162,7 +189,7 @@ vec_iter_fwd(struct vec *vec, void **p) { void **iter; - LIBVEC_ASSERT(vec != NULL && p != NULL); + LIBVEC_CHECK(vec != NULL && p != NULL); if (!vec->len) return false; @@ -181,7 +208,7 @@ vec_iter_bwd(struct vec *vec, void **p) { void **iter; - LIBVEC_ASSERT(vec != NULL && p != NULL); + LIBVEC_CHECK(vec != NULL && p != NULL); if (!vec->len) return false;