commit 050c64b1c4f70112e85a712398d0fd74895e7d05 Author: Ava Affine Date: Wed Apr 29 20:01:50 2026 +0000 whatever was in here to start with Signed-off-by: Ava Affine diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..e8537f1 --- /dev/null +++ b/.clangd @@ -0,0 +1,3 @@ +CompileFlags: + Compiler: gcc + Add: ["-xc", "-std=c2x"] diff --git a/src/aerr.h b/src/aerr.h new file mode 100644 index 0000000..1071965 --- /dev/null +++ b/src/aerr.h @@ -0,0 +1,10 @@ +typedef enum { + A_ERROR = 0, + A_OK, + A_DONE, + A_AGAIN, + A_SKIPPED, + A_REFUSED, + A_UNKNOWN, + A_OUTOFBOUND, +} aret; diff --git a/src/alog.h b/src/alog.h new file mode 100644 index 0000000..92d8e6b --- /dev/null +++ b/src/alog.h @@ -0,0 +1,17 @@ +#include +#include + +typedef enum { + A_DEBUG = 0, + A_INFO, + A_WARN, + A_ERROR, + A_CRITICAL, +} aloglev; + +void alog(aloglev level, const char *tmpl, ...) { + va_list args; + va_start(args, tmpl); + vfprintf(stdout, tmpl, args); + va_end(args); +} diff --git a/src/amem.h b/src/amem.h new file mode 100644 index 0000000..d20675e --- /dev/null +++ b/src/amem.h @@ -0,0 +1,55 @@ +#include +#include + + +// TODO: page based memory allocator + + +typedef struct { + // TODO +} apool; + +typedef void *(*malloc_f) (size_t); +typedef void *(*calloc_f) (size_t, size_t); +typedef void *(*realloc_f)(void *, size_t); +typedef void (*free_f) (void *); + +static malloc_f __alib_malloc = malloc; +static calloc_f __alib_calloc = calloc; +static realloc_f __alib_realloc = realloc; +static free_f __alib_free = free; + +void *amalloc(size_t sz, apool *_) { + // TODO: use pool if provided + return __alib_malloc(sz); +} + +void *acalloc(size_t sz, size_t ct, apool *_) { + return __alib_calloc(sz, ct); +} + +void *arealloc(void *ptr, size_t newsz, apool *_) { + return __alib_realloc(ptr, newsz); +} + +void afree(void *p, apool *_) { + __alib_free(p); +} + +#if (ALIB_HIJACK) +void free(void *p) { + afree(p, NULL); +} + +void *calloc(size_t sz, size_t ct) { + return acalloc(sz, ct, NULL); +} + +void *malloc(size_t sz) { + return amalloc(sz, NULL); +} + +void *realloc(void *p, size_t sz) { + return arealloc(p, sz, NULL); +} +#endif diff --git a/src/astr.h b/src/astr.h new file mode 100644 index 0000000..fa7f3a9 --- /dev/null +++ b/src/astr.h @@ -0,0 +1,70 @@ +#include +#include +#include + +#include "amem.h" + +typedef struct { + char *src; + uintptr_t start, end; +} astr; + +#define atoraw(in) &in->src[in->start] +#define astr(in) {in, 0, sizeof(in) - 1} +#define astrlen(in) in->end - in->start +#define astr_empty() {NULL, 0, 0} +#define astr_isempty(in) !in.src && !in.start && !in.end + +astr asubstr(const astr *src, int start_offset, int end_offset) { + if ((start_offset < 0 && abs(start_offset) > src->start) || + (end_offset > 0)) { + astr ret = astr_empty(); + return ret; + } + + astr ret = { + src->src, + src->start + start_offset, + src->end + end_offset + }; + return ret; +} + +char *astr_copy_view(const astr *src, apool *p) { + char *out = NULL; + + if ((out = amalloc(src->end - src->start, p))) { + memcpy(out, src->src, src->end - src->start); + } + + return out; +} + +astr *astrdup_shallow(const astr *src, apool *p) { + astr *out; + + if ((out = amalloc(sizeof(astr), p))) { + out->src = src->src; + out->start = src->start; + out->end = src->end; + return out; + } + + return NULL; +} + +astr *astrdup_deep(const astr *src, apool *p) { + astr *out; + + if ((out = amalloc(sizeof(astr), p))) { + if ((out->src = astr_copy_view(src, p))) { + out->start = src->start; + out->end = src->end; + return out; + } + + afree(out, p); + } + + return NULL; +} diff --git a/src/skbuf.h b/src/skbuf.h new file mode 100644 index 0000000..27f1cf8 --- /dev/null +++ b/src/skbuf.h @@ -0,0 +1,199 @@ +#include +#include +#include +#include + +#include "amem.h" +#include "aerr.h" + +struct skbuf_s; +typedef struct skbuf_s skbuf; + +struct skbuf_s { + uintptr_t size; + skbuf *next; + char data[]; +}; + +skbuf *skbuf_new(size_t sz, size_t ct, apool *p) { + if (!sz || !ct) return NULL; + + skbuf *out = NULL; + + if ((out = amalloc(sz * ct + sizeof(skbuf), p))) { + out->size = ct * sz; + out->next = NULL; + } + + return out; +} + +void *skbuf_push(skbuf *buf, size_t sz, size_t ct, apool *p) { + if (!sz || !ct) return NULL; + if (buf->next) return skbuf_push(buf->next, sz, ct, p); + + if ((buf->next = skbuf_new(sz, ct, p))) { + return (void *) buf->next->data; + } + + return NULL; +} + +void *skbuf_idx(skbuf *buf, size_t sz, size_t idx) { + if (idx * sz >= buf->size) { + return buf->next ? + skbuf_idx(buf->next, sz, idx - (buf->size / sz)) : + NULL; + } + + return &buf->data[idx * sz]; +} + +skbuf *skbuf_mkcontiguous(skbuf *buf, apool *p) { + size_t capacity = 0; + skbuf *out = NULL; + + for (skbuf *i = buf; i; i = i->next) { + capacity += buf->size; + } + + if ((out = skbuf_new(capacity, 1, p))) { + size_t cur = 0; + for (skbuf *i = buf; i; i = i->next) { + memcpy(&out->data[cur], i->data, i->size); + cur += i->size; + } + } + + return out; +} + +int skbuf_idx_remove(skbuf *buf, size_t idx, size_t sz, apool *p) { + skbuf *i = buf, *j; + char *cur = NULL; + + if (!sz) return A_REFUSED; + + while (i->next) { + if (idx * sz > i->size + i->next->size) { + idx -= i->size / sz; + i = i->next; + } else break; + } + + // its in this skbuf + if (idx * sz <= i->size && i->size - (idx * sz) >= sz) { + cur = &i->data[idx * sz]; + if (i->size > idx * sz) { + memcpy(cur, cur + sz, sz); + } + + i->size -= sz; + arealloc(i, i->size, p); + + // its in the next skbuf + } else if (idx * sz <= i->next->size && i->next->size - (idx * sz) >= sz) { + cur = &i->next->data[idx * sz]; + if (i->next->size > idx * sz) { + memcpy(cur, cur + sz, sz); + } + + i->next->size -= sz; + if (i->next->size) { + arealloc(i, i->size, p); + + // reclaim + } else { + j = i->next; + i->next = i->next->next; + afree(j, p); + } + + // idx past array bounds or lies partially outsize of a buffer + } else { + return A_OUTOFBOUND; + } + + return A_OK; +} + +int skbuf_frag_pop(skbuf *buf, size_t frag_idx, apool *p) { + if (!frag_idx) { + if (buf->next) return A_REFUSED; + afree(buf, p); + return A_OK; + } + + if (!buf->next) return A_OUTOFBOUND; + if (frag_idx == 1) { + afree(buf->next, p); + return A_OK; + } + + return skbuf_frag_pop(buf->next, --frag_idx, p); +} + +int skbuf_len(skbuf *buf, size_t sz) { + return buf->size / sz + (buf->next ? skbuf_len(buf->next, sz) : 0); +} + +void *skbuf_reduce( + skbuf *buf, + size_t sz, + void (reduce_fn)(void *carry, void *input), + apool *p +) { + if (!sz || !buf->size) return NULL; + + size_t cur; + void *out; + + if (!(out = amalloc(sz, p))) { + return NULL; + } + + for (; buf; buf = buf->next) { + cur = 0; + while (cur < buf->size) { + reduce_fn(out, &buf->data[cur]); + cur += sz; + } + // can detect here the state of excess bytes if sz != original obj size + } + + return out; +} + +static void _skbuf_map_reduce_fn(void *carry, void *input) { + skbuf *arr = (skbuf *) carry; + size_t sz = arr->size; + apool *p = * (void **) (&arr->data); + void *out = skbuf_push(arr, sz, 1, p); + + if (out) memcpy(out, input, sz); +} + +skbuf *skbuf_map( + skbuf *buf, + size_t sz, + void (map_fn)(void *src, void *dest), + apool *p +) { + if (!buf->size) return NULL; + + size_t ct = 0; + size_t cur = 0; + skbuf *out, *tmp; + void *obj, *in; + apool **pl; + + if (!(out = skbuf_new(sizeof(apool *), 1, p))) return NULL; + out->size = sz; + pl = (apool **) out->data; + *pl = p; + + tmp = out; + out = out->next; + afree(tmp, p); + return out; +}