whatever was in here to start with
Signed-off-by: Ava Affine <ava@sunnypup.io>
This commit is contained in:
commit
050c64b1c4
6 changed files with 354 additions and 0 deletions
3
.clangd
Normal file
3
.clangd
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
CompileFlags:
|
||||
Compiler: gcc
|
||||
Add: ["-xc", "-std=c2x"]
|
||||
10
src/aerr.h
Normal file
10
src/aerr.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
typedef enum {
|
||||
A_ERROR = 0,
|
||||
A_OK,
|
||||
A_DONE,
|
||||
A_AGAIN,
|
||||
A_SKIPPED,
|
||||
A_REFUSED,
|
||||
A_UNKNOWN,
|
||||
A_OUTOFBOUND,
|
||||
} aret;
|
||||
17
src/alog.h
Normal file
17
src/alog.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
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);
|
||||
}
|
||||
55
src/amem.h
Normal file
55
src/amem.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
// 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
|
||||
70
src/astr.h
Normal file
70
src/astr.h
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
199
src/skbuf.h
Normal file
199
src/skbuf.h
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
#include <float.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue