(45 minutes ago)commit 7790c99: Meh. Halfway vector implementation. Not happy with the name
| author | Tanner Stenson <tanner@brickware.sh> |
| date | Thu Jan 8 20:26:10 2026 -0500 |
Meh. Halfway vector implementation. Not happy with the name
commit 7790c9920757f1cf598083ee72659023393b901c
Author: Tanner Stenson <tanner@brickware.sh>
Date: Thu Jan 8 20:26:10 2026 -0500
Meh. Halfway vector implementation. Not happy with the name
diff --git a/Makefile b/Makefile
index a0e9aa9..183f8be 100644
--- a/Makefile
+++ b/Makefile
@@ -8,10 +8,10 @@ TARGETS = marrow-auth marrow-shell marrow-static
all: $(TARGETS)
-marrow-auth: marrow-auth.o slice.o
+marrow-auth: marrow-auth.o slice_fromcstr.o
$(CC) $(CFLAGS) -o $@ $>
-marrow-shell: marrow-shell.o slice.o
+marrow-shell: marrow-shell.o slice_empty.o slice_fromcstr.o slice_isempty.o
$(CC) $(CFLAGS) -o $@ $>
marrow-static: marrow-static.o
diff --git a/allocator.h b/allocator.h
new file mode 100644
index 0000000..958c705
--- /dev/null
+++ b/allocator.h
@@ -0,0 +1,14 @@
+#ifndef __ALLOCATOR_H
+#define __ALLOCATOR_H
+
+struct allocator {
+ void *(*alloc)(size_t num, size_t size);
+ void *(*realloc)(void *ptr, size_t num, size_t size);
+ void (*free)(void *ptr);
+};
+
+/* default allocator
+ */
+extern const struct allocator defalloc;
+
+#endif
diff --git a/defalloc.c b/defalloc.c
new file mode 100644
index 0000000..c811559
--- /dev/null
+++ b/defalloc.c
@@ -0,0 +1,45 @@
+#include <stdlib.h>
+
+#include "./allocator.h"
+
+
+static inline void *
+__calloc2(const size_t num, const size_t size);
+
+static inline void *
+__realloc3(void *ptr, const size_t num, const size_t size);
+
+static inline void
+__free1(void *ptr);
+
+
+static inline void *
+__calloc2(const size_t num, const size_t size)
+{
+ return calloc(num, size);
+}
+
+static inline void *
+__realloc3(void *ptr, const size_t num, const size_t size)
+{
+ if (0x00 != ptr) {
+ return realloc(ptr, num * size);
+ }
+
+ return __calloc2(num, size);
+}
+
+static inline void
+__free1(void *ptr)
+{
+ if (0x00 != ptr) {
+ free(ptr);
+ }
+}
+
+
+const struct allocator defalloc = {
+ .alloc = __calloc2,
+ .realloc = __realloc3,
+ .free = __free1
+};
diff --git a/ldup.c b/ldup.c
new file mode 100644
index 0000000..3e674f7
--- /dev/null
+++ b/ldup.c
@@ -0,0 +1,24 @@
+/***
+ * ldup.c
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "./allocator.h"
+#include "./vector.h"
+
+
+int32_t
+ldup(const struct allocator alloc, void **dest, size_t *const length, const void *src, const size_t num, const size_t size)
+{
+ int32_t rc;
+
+ rc = lensure(alloc, dest, length, 0, num, size);
+ if (VEC_OKAY == rc) {
+ memcpy(*dest, src, num * size);
+ }
+
+ return (rc);
+}
diff --git a/linsert.c b/linsert.c
new file mode 100644
index 0000000..c4e5ce7
--- /dev/null
+++ b/linsert.c
@@ -0,0 +1,15 @@
+/***
+ * linsert.c
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "./allocator.h"
+#include "./vector.h"
+
+int32_t
+linsert(void *dest, const size_t length, const size_t num, const size_t size, const size_t index, const void *item)
+{
+ return (linserts(dest, length, num, size, index, item, 1));
+}
diff --git a/linserts.c b/linserts.c
new file mode 100644
index 0000000..d07142f
--- /dev/null
+++ b/linserts.c
@@ -0,0 +1,30 @@
+/***
+ * linserts.c
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "./allocator.h"
+#include "./vector.h"
+
+
+int32_t
+linserts(void *dest, const size_t length, const size_t num, const size_t size, const size_t index, const void *items, const size_t count)
+{
+ /* if list isn't large enough, fail */
+ if ((length - num) < count) {
+ return (VEC_ERR_NOSPACE);
+ }
+
+ /* shift data to the right */
+ if (index < num) {
+ memmove(VECITEM(dest, index + count, size),
+ VECITEM(dest, index, size),
+ size * (num - index));
+ }
+
+ memcpy(VECITEM(dest, index, size), items, count * size);
+ return (VEC_OKAY);
+}
diff --git a/lpush.c b/lpush.c
new file mode 100644
index 0000000..0794b2d
--- /dev/null
+++ b/lpush.c
@@ -0,0 +1,16 @@
+/***
+ * lpush.c
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "./allocator.h"
+#include "./vector.h"
+
+
+int32_t
+lpush(void *dest, const size_t length, const size_t num, const size_t size, const void *item)
+{
+ return (linsert(dest, length, num, size, num, item));
+}
diff --git a/marrow-static.c b/marrow-static.c
index e8823a7..526e35f 100644
--- a/marrow-static.c
+++ b/marrow-static.c
@@ -1,3 +1,6 @@
+/***
+ * marrow-static.c
+ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -12,6 +15,7 @@
#define MAX_LINE_LEN 2048
#define DEFAULT_GIT_BASE_PATH "/srv/git"
+
/* Repository metadata for directory index generation */
struct repo_info {
char name[PATH_MAX];
diff --git a/slice.c b/slice.c
deleted file mode 100644
index 9ce19c3..0000000
--- a/slice.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include "./slice.h"
-
-
-struct slice
-slice_fromcstr(const char *s) {
- struct slice result;
-
- result.ptr = s;
- result.size = strlen(s);
-
- return (result);
-}
-
-int32_t
-slice_isempty(const struct slice s) {
- if (0 == s.size) return (1);
- return (0);
-}
-
-struct slice
-slice_empty(void) {
- return (struct slice){
- .ptr = 0x00,
- .size = 0,
- };
-}
-
-char *
-slice_tocstr(const struct slice s) {
- if (0 == s.ptr || 0 == s.size) {
- return 0x00;
- }
-
- char *str = malloc(s.size + 1);
- if (!str) {
- return 0x00;
- }
-
- memcpy(str, s.ptr, s.size);
- str[s.size] = '\0';
- return str;
-}
diff --git a/slice_empty.c b/slice_empty.c
new file mode 100644
index 0000000..90b9d00
--- /dev/null
+++ b/slice_empty.c
@@ -0,0 +1,17 @@
+/***
+ * slice_empty.c
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "./slice.h"
+
+
+struct slice
+slice_empty(void) {
+ return (struct slice){
+ .ptr = 0x00,
+ .size = 0,
+ };
+}
diff --git a/slice_fromcstr.c b/slice_fromcstr.c
new file mode 100644
index 0000000..542e52c
--- /dev/null
+++ b/slice_fromcstr.c
@@ -0,0 +1,20 @@
+/***
+ * slice_fromcstr.c
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "./slice.h"
+
+
+struct slice
+slice_fromcstr(const char *s) {
+ struct slice result;
+
+ result.ptr = s;
+ result.size = strlen(s);
+
+ return (result);
+}
diff --git a/slice_isempty.c b/slice_isempty.c
new file mode 100644
index 0000000..3e9d726
--- /dev/null
+++ b/slice_isempty.c
@@ -0,0 +1,16 @@
+/***
+ * slice_isempty.c
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "./slice.h"
+
+
+
+int32_t
+slice_isempty(const struct slice s) {
+ if (0 == s.size) return (1);
+ return (0);
+}
diff --git a/slice_tocstr.c b/slice_tocstr.c
new file mode 100644
index 0000000..748e0e2
--- /dev/null
+++ b/slice_tocstr.c
@@ -0,0 +1,26 @@
+/***
+ * slice_tocstr.c
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "./slice.h"
+
+
+char *
+slice_tocstr(const struct slice s) {
+ if (0 == s.ptr || 0 == s.size) {
+ return 0x00;
+ }
+
+ char *str = malloc(s.size + 1);
+ if (!str) {
+ return 0x00;
+ }
+
+ memcpy(str, s.ptr, s.size);
+ str[s.size] = '\0';
+ return str;
+}
diff --git a/vector.h b/vector.h
new file mode 100644
index 0000000..d55b6c1
--- /dev/null
+++ b/vector.h
@@ -0,0 +1,183 @@
+#ifndef __VECTOR_H
+#define __VECTOR_H
+
+
+#define FASTCMP(a, b) ( ((a) > (b)) - ((a) < (b)) )
+
+#define VEC_OKAY ( 0)
+#define VEC_ERR_ALLOC (-1) /* allocation failure */
+#define VEC_ERR_NOSPACE (-2) /* capacity failure */
+
+#define VECITEM(p, i, s) (((uint8_t *)(p)) + ((i) * (s)))
+#define VECITEM_CAST(p, i, t) ((t *)VECITEM((p), (i), (sizeof(t))))
+
+
+/* access patterns for searching a list
+ */
+enum seek_mode {
+ SEEK_SEQUENTIAL
+, SEEK_BINARY
+};
+
+typedef int32_t (*comparator)(const void *a, const void *b);
+
+/* qsort_r is a non-standard function call, meaning different platforms
+ * have different signatures.
+ */
+#ifdef __FreeBSD__
+typedef int32_t (*comparator_r)(void *data, const void *a, const void *b);
+#define DEFINE_COMPARATOR_R(name) int32_t name(void *data, const void *a, const void *b)
+#else
+typedef int32_t (*comparator_r)(const void *a, const void *b, void *data);
+#define DEFINE_COMPARATOR_R(name) int32_t name(const void *a, const void *b, void *data)
+#endif
+
+/* simple list structure containing all details necessary for managing a
+ * generic list
+ */
+struct vector {
+ void *ptr;
+ size_t capacity;
+ size_t length;
+ size_t size;
+};
+
+/*
+ * safe list allocation
+ *
+ * allocations (or reallocates) memory large enough to contain `num` elements
+ * of size `size`. if `ptr` is NUL, allocation is attempted, otherwise `ptr`
+ * is reallocated to the requested size.
+ *
+ * parameters:
+ * - (alloc) allocator to use for memory allocation
+ * - (ptr) original pointer
+ * - (num) number of elements to allocate
+ * - (size) size of each element
+ *
+ * returns:
+ * a pointer to the newly allocated memory on success or a NUL pointer
+ * on failure.
+ */
+void *
+lalloc(const struct allocator alloc, void *ptr, const size_t num, const size_t size);
+
+
+/* ensure list length
+ *
+ * ensure the given list has the capacity to store `cap` more elements. if
+ * not, attempt to resize it.
+ *
+ * parameters:
+ * - (alloc) allocator to use for memory allocation
+ * - (dest) pointer to list
+ * - (length) total element capacity in list `dest`
+ * - (num) number of elements currently in list `dest`
+ * - (cap) number of elements to be added to list `dest`
+ * - (size) size of an element in list `dest`
+ *
+ * returns:
+ * VEC_OKAY on capacity available.
+ * VEC_OKAY if list was resized and capacity is available.
+ * VEC_ERR_ALLOC if resize failed.
+ */
+int32_t
+lensure(const struct allocator alloc, void **dest, size_t *const length, const size_t num, const size_t cap, const size_t size);
+
+
+/* list duplicate
+ *
+ * create a copy of an anonymous list
+ *
+ * parameters:
+ * - (alloc) allocator to use for memory allocation
+ * - (dest) pointer to allocate for duplicated list
+ * - (length) total element capacity in list `dest`
+ * - (src) list to duplicate
+ * - (num) number of elements currently in list `src`
+ * - (size) size of an element in list `src`
+ *
+ * returns:
+ * VEC_OKAY on successful duplication.
+ * VEC_ERR_ALLOC if allocation failed.
+ */
+int32_t
+ldup(const struct allocator alloc, void **dest, size_t *const length, const void *src, const size_t num, const size_t size);
+
+/* list insert many
+ *
+ * insert a list of elements into a list at the specific index.
+ * if space isn't available, the operation will fail.
+ *
+ * parameters:
+ * - (dest) pointer to list
+ * - (length) total element capacity in list `dest`
+ * - (num) number of elements current in the list `dest`
+ * - (size) size of an element in list `dest`
+ * - (index) position to insert `items` at
+ * - (items) elements to insert into `dest`
+ * - (count) number of elements in `items` to insert
+ *
+ * returns:
+ * VEC_OKAY on success.
+ * VEC_ERR_NOSPACE on not enough available space.
+ */
+int32_t
+linserts(void *dest, const size_t length, const size_t num, const size_t size, const size_t index, const void *items, const size_t count);
+
+/* list insert singular
+ *
+ * insert an element into a list at the specific index.
+ * if space isn't available, the operation will fail.
+ *
+ * parameters:
+ * - (dest) pointer to list
+ * - (length) total element capacity in list `dest`
+ * - (num) number of elements currently in the list `dest`
+ * - (size) size of an element in list `dest`
+ * - (index) position to insert `item` at
+ * - (item) element to insert into `dest`
+ *
+ * returns:
+ * VEC_OKAY on success.
+ * VEC_ERR_NOSPACE on not enough available space.
+ */
+int32_t
+linsert(void *dest, const size_t length, const size_t num, const size_t size, const size_t index, const void *item);
+
+/* list push
+ *
+ * append an item to the end of an anonymous pointer.
+ * if space isn't available, the operation will fail.
+ *
+ * parameters:
+ * - (dest) pointer to list
+ * - (length) total element capacity in list `dest`
+ * - (num) number of elements currently in list `dest`
+ * - (size) size of an element in list `dest`
+ * - (item) element to append to list `dest`
+ *
+ * returns:
+ * VEC_OKAY on success.
+ * VEC_ERR_NOSPACE on no available space.
+ */
+int32_t
+lpush(void *dest, const size_t length, const size_t num, const size_t size, const void *item);
+
+/* TODO
+ * lsort
+ * lsort_r
+ * lindexof_mode
+ * lindexof_mode_r
+ * lindexof_r
+ * lindexof
+ * ldedup
+ * ldedup_r
+ *
+ * vec_push
+ * vec_indexof_mode_r
+ * vec_indexof_mode
+ * vec_indexof_r
+ */
+
+#endif