git / brickware / marrow.git - 7790c99

(45 minutes ago)commit 7790c99: Meh. Halfway vector implementation. Not happy with the name

Summary | History | Files

commit 7790c99

authorTanner Stenson <tanner@brickware.sh>
dateThu Jan 8 20:26:10 2026 -0500

message

Meh. Halfway vector implementation. Not happy with the name

diff

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