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:
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;