From 24f4962d8c8a1caae2905e11e9232d85650dcd91 Mon Sep 17 00:00:00 2001 From: Aryadev Chavali Date: Tue, 10 Mar 2026 21:08:24 +0000 Subject: [PATCH] extracted prick into their own header files and deleted lib --- lib/prick_aliases.h => base.h | 28 +++--- build.sh | 2 +- lib/prick_vec.h | 163 ---------------------------------- main.c | 13 +-- lib/prick_sv.h => sv.c | 64 ++++--------- sv.h | 50 +++++++++++ vec.c | 111 +++++++++++++++++++++++ vec.h | 55 ++++++++++++ 8 files changed, 250 insertions(+), 236 deletions(-) rename lib/prick_aliases.h => base.h (56%) delete mode 100644 lib/prick_vec.h rename lib/prick_sv.h => sv.c (52%) create mode 100644 sv.h create mode 100644 vec.c create mode 100644 vec.h diff --git a/lib/prick_aliases.h b/base.h similarity index 56% rename from lib/prick_aliases.h rename to base.h index a25440c..f98c833 100644 --- a/lib/prick_aliases.h +++ b/base.h @@ -1,15 +1,11 @@ -/* prick_aliases.h: - * Created: 2025-04-09 +/* base.h: Basic definitions + * Created: 2026-03-10 * Author: Aryadev Chavali * License: See end of file - * Commentary: - - This library defines some useful aliases for common types. These are mostly - handpicked, and aren't necessary. */ -#ifndef PRICK_ALIASES_H -#define PRICK_ALIASES_H +#ifndef BASE_H +#define BASE_H #include #include @@ -29,16 +25,22 @@ static_assert(sizeof(double) == 8, "f64 requires 8 byte doubles"); typedef float f32; typedef double f64; +#define MAX(A, B) ((A) > (B) ? (A) : (B)) +#define SAFE_SUB(A, B) ((A) < (B) ? 0 : (A) - (B)) +// 64 byte programs +#define SIZEOF_PROGRAM (1LU << 6) + #endif -/* Copyright (C) 2025 Aryadev Chavali +/* Copyright (C) 2026 Aryadev Chavali * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the Unlicense for details. + * FOR A PARTICULAR PURPOSE. See the GNU General Public License Version 2 for + * details. - * You may distribute and modify this code under the terms of the Unlicense, - * which you should have received a copy of along with this program. If not, - * please go to . + * You may distribute and modify this code under the terms of the GNU General + * Public License Version 2, which you should have received a copy of along with + * this program. If not, please go to . */ diff --git a/build.sh b/build.sh index 20d3449..2fc0bce 100644 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ CFLAGS="-Wall -Wextra -Wpedantic -Wswitch-enum -Werror -std=c23 -ggdb" LDFLAGS="-lm -lraylib" -SRC="main.c" +SRC="sv.c vec.c main.c" OUT="main.out" set -xe diff --git a/lib/prick_vec.h b/lib/prick_vec.h deleted file mode 100644 index 9a15353..0000000 --- a/lib/prick_vec.h +++ /dev/null @@ -1,163 +0,0 @@ -/* prick_vec.h: A dynamically sized array with SBO. - * Created: 2026-01-22 - * Author: Aryadev Chavali - * License: See end of file - * Commentary: - - To utilise this library, please put: - #define PRICK_VEC_IMPL - #include "prick_vec.h" - in one of your code units. - - This library defines another form of dynamically sized array as opposed to - prick_darr.h. This one is closer to the one classically implemented by most; a - structure with some metadata and a pointer to the raw buffer. This way, - pointers to the dynamic array are stable (as the structure itself is never - reallocated) and the array can still grow as required. - - We use a trick, called Small Buffer Optimisation (SBO), to inline elements - directly into the structure when there are a small number of them (see - PRICK_VEC_INLINE_CAPACITY). This makes lookup _even faster_ (no derefence and - possibility of the entire vector existing in the CPU cache) and allows us to - avoid allocation for smaller use cases. If the number of elements exceeds - PRICK_VEC_INLINE_CAPACITY, we utilise the allocator. - */ - -#ifndef PRICK_VEC_H -#define PRICK_VEC_H - -#include -#include -#include - -#define VEC_INLINE_CAPACITY 32 -#define VEC_MULT 2 - -typedef struct -{ - uint64_t size, capacity; - uint8_t not_inlined; - union - { - void *ptr; - alignas(max_align_t) uint8_t inlined[VEC_INLINE_CAPACITY]; - }; -} vec_t; - -static_assert(sizeof(vec_t) == 64, "Expected sizeof(vec_t) to be 64"); - -void vec_append(vec_t *vec, const void *const ptr, uint64_t size); -void vec_append_byte(vec_t *vec, uint8_t byte); -void *vec_data(vec_t *vec); -void vec_ensure_capacity(vec_t *vec, uint64_t capacity); -void vec_ensure_free(vec_t *vec, uint64_t size); -void vec_free(vec_t *vec); -void vec_clone(vec_t *v2, vec_t *v1); - -#define VEC_GET(VEC, INDEX, TYPE) (((TYPE *)vec_data(VEC))[INDEX]) - -#ifdef VEC_IMPL -#define MAX(A, B) ((A) > (B) ? (A) : (B)) - -#include -#include - -void vec_append(vec_t *vec, const void *const ptr, uint64_t size) -{ - if (!vec || !ptr || !size) - return; - vec_ensure_free(vec, size); - memcpy(&VEC_GET(vec, vec->size, uint8_t), ptr, size); - vec->size += size; -} - -void vec_append_byte(vec_t *vec, uint8_t byte) -{ - if (!vec) - return; - vec_ensure_free(vec, 1); - VEC_GET(vec, vec->size, uint8_t) = byte; - ++vec->size; -} - -void *vec_data(vec_t *vec) -{ - if (!vec) - return NULL; - - if (vec->not_inlined) - { - return vec->ptr; - } - else - { - return vec->inlined; - } -} - -void vec_ensure_capacity(vec_t *vec, uint64_t capacity) -{ - if (!vec) - return; - if (vec->capacity == 0) - vec->capacity = VEC_INLINE_CAPACITY; - if (vec->capacity < capacity) - { - vec->capacity = MAX(vec->capacity * VEC_MULT, capacity); - if (!vec->not_inlined) - { - // We were a small buffer, and now we cannot be i.e. we need to allocate - // on the heap. - vec->not_inlined = 1; - void *buffer = calloc(1, vec->capacity); - memcpy(buffer, vec->inlined, vec->size); - memset(vec->inlined, 0, sizeof(vec->inlined)); - vec->ptr = buffer; - } - else - { - // We're already on the heap, just reallocate. - vec->ptr = realloc(vec->ptr, vec->capacity); - } - } -} - -void vec_ensure_free(vec_t *vec, uint64_t size) -{ - if (!vec) - return; - vec_ensure_capacity(vec, vec->size + size); -} - -void vec_free(vec_t *vec) -{ - if (!vec) - return; - if (vec->not_inlined) - free(vec->ptr); - memset(vec, 1, sizeof(*vec)); -} - -void vec_clone(vec_t *v2, vec_t *v1) -{ - if (!v1 || !v2) - return; - vec_append(v2, vec_data(v1), v1->size); -} - -#undef MAX -#endif - -#endif - -/* Copyright (C) 2026 Aryadev Chavali - - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the Unlicense for details. - - * You may distribute and modify this code under the terms of the Unlicense, - * which you should have received a copy of along with this program. If not, - * please go to . - - */ diff --git a/main.c b/main.c index 3325499..3af069f 100644 --- a/main.c +++ b/main.c @@ -10,17 +10,10 @@ #include #include -#include "./lib/prick_aliases.h" +#include "base.h" +#include "sv.h" +#include "vec.h" -#define SV_IMPL -#include "./lib/prick_sv.h" - -#define VEC_IMPL -#include "./lib/prick_vec.h" - -#define SAFE_SUB(A, B) ((A) < (B) ? 0 : (A) - (B)) - -#define SIZEOF_PROGRAM (1LU << 6) struct ProgramConcat { sv_t A, B; diff --git a/lib/prick_sv.h b/sv.c similarity index 52% rename from lib/prick_sv.h rename to sv.c index 08f3ef6..0628aec 100644 --- a/lib/prick_sv.h +++ b/sv.c @@ -1,49 +1,16 @@ -/* sv.h: String Views. - * Created: 2026-03-01 +/* sv.c: String View implementation + * Created: 2026-03-10 * Author: Aryadev Chavali * License: See end of file * Commentary: - - To utilise this library, please put: - #define SV_IMPL - #include "sv.h" - in one of your code units. - - This is a simple read-only string view library. It defines some extremely - common functions you'd expect for a string view library, excluding any that - require allocation. + Taken from https://github.com/oreodave/prick - prick_sv. */ -#ifndef SV_H -#define SV_H - -#include - -typedef struct -{ - uint64_t size; - const char *data; -} sv_t; - -#define SV(DATA, SIZE) ((sv_t){.data = (DATA), .size = (SIZE)}) -#define SV_AUTO(DATA) ((sv_t){.data = (void *)(DATA), .size = sizeof(DATA) - 1}) - -// Pretty printers -#define SV_FMT(SV) (int)(SV).size, (SV).data -#define PR_SV "%.*s" - -sv_t sv_chop_left(sv_t, uint64_t size); -sv_t sv_chop_right(sv_t, uint64_t size); -sv_t sv_truncate(sv_t, uint64_t newsize); -sv_t sv_substr(sv_t, uint64_t position, uint64_t size); - -sv_t sv_till(sv_t, const char *reject); -sv_t sv_while(sv_t, const char *accept); - -#ifdef SV_IMPL #include #include +#include "sv.h" + sv_t sv_chop_left(sv_t sv, uint64_t size) { if (sv.size <= size) @@ -97,18 +64,17 @@ sv_t sv_while(sv_t sv, const char *accept) return sv_truncate(sv, offset); } -#endif - -#endif - /* Copyright (C) 2026 Aryadev Chavali - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the Unlicense for details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + Public License Version 2 + * for details. - * You may distribute and modify this code under the terms of the Unlicense, - * which you should have received a copy of along with this program. If not, - * please go to . + * You may distribute and modify this code under the terms of the + * GNU General Public License Version 2, which you should have received a copy + of along with this + * program. If not, please go to . - */ +*/ diff --git a/sv.h b/sv.h new file mode 100644 index 0000000..df28e3c --- /dev/null +++ b/sv.h @@ -0,0 +1,50 @@ +/* sv.h: String Views + * Created: 2026-03-10 + * Author: Aryadev Chavali + * License: See end of file + * Commentary: + Taken from https://github.com/oreodave/prick - prick_sv. + */ + +#ifndef SV_H +#define SV_H + +#include + +typedef struct +{ + uint64_t size; + const char *data; +} sv_t; + +#define SV(DATA, SIZE) ((sv_t){.data = (DATA), .size = (SIZE)}) +#define SV_AUTO(DATA) ((sv_t){.data = (void *)(DATA), .size = sizeof(DATA) - 1}) + +// Pretty printers +#define SV_FMT(SV) (int)(SV).size, (SV).data +#define PR_SV "%.*s" + +sv_t sv_chop_left(sv_t, uint64_t size); +sv_t sv_chop_right(sv_t, uint64_t size); +sv_t sv_truncate(sv_t, uint64_t newsize); +sv_t sv_substr(sv_t, uint64_t position, uint64_t size); + +sv_t sv_till(sv_t, const char *reject); +sv_t sv_while(sv_t, const char *accept); + +#endif + +/* Copyright (C) 2026 Aryadev Chavali + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + Public License Version 2 + * for details. + + * You may distribute and modify this code under the terms of the + * GNU General Public License Version 2, which you should have received a copy + of along with this + * program. If not, please go to . + +*/ diff --git a/vec.c b/vec.c new file mode 100644 index 0000000..3229169 --- /dev/null +++ b/vec.c @@ -0,0 +1,111 @@ +/* vec.c: Vector implementation + * Created: 2026-03-10 + * Author: Aryadev Chavali + * License: See end of file + * Commentary: + Taken from https://github.com/oreodave/prick - prick_vec. + */ + +#include +#include + +#include "base.h" +#include "vec.h" + +void vec_append(vec_t *vec, const void *const ptr, uint64_t size) +{ + if (!vec || !ptr || !size) + return; + vec_ensure_free(vec, size); + memcpy(&VEC_GET(vec, vec->size, uint8_t), ptr, size); + vec->size += size; +} + +void vec_append_byte(vec_t *vec, uint8_t byte) +{ + if (!vec) + return; + vec_ensure_free(vec, 1); + VEC_GET(vec, vec->size, uint8_t) = byte; + ++vec->size; +} + +void *vec_data(vec_t *vec) +{ + if (!vec) + return NULL; + + if (vec->not_inlined) + { + return vec->ptr; + } + else + { + return vec->inlined; + } +} + +void vec_ensure_capacity(vec_t *vec, uint64_t capacity) +{ + if (!vec) + return; + if (vec->capacity == 0) + vec->capacity = VEC_INLINE_CAPACITY; + if (vec->capacity < capacity) + { + vec->capacity = MAX(vec->capacity * VEC_MULT, capacity); + if (!vec->not_inlined) + { + // We were a small buffer, and now we cannot be i.e. we need to allocate + // on the heap. + vec->not_inlined = 1; + void *buffer = calloc(1, vec->capacity); + memcpy(buffer, vec->inlined, vec->size); + memset(vec->inlined, 0, sizeof(vec->inlined)); + vec->ptr = buffer; + } + else + { + // We're already on the heap, just reallocate. + vec->ptr = realloc(vec->ptr, vec->capacity); + } + } +} + +void vec_ensure_free(vec_t *vec, uint64_t size) +{ + if (!vec) + return; + vec_ensure_capacity(vec, vec->size + size); +} + +void vec_free(vec_t *vec) +{ + if (!vec) + return; + if (vec->not_inlined) + free(vec->ptr); + memset(vec, 1, sizeof(*vec)); +} + +void vec_clone(vec_t *v2, vec_t *v1) +{ + if (!v1 || !v2) + return; + vec_append(v2, vec_data(v1), v1->size); +} + +/* Copyright (C) 2026 Aryadev Chavali + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + Public License Version 2 + * for details. + + * You may distribute and modify this code under the terms of the + * GNU General Public License Version 2, which you should have received a copy + of along with this + * program. If not, please go to . + +*/ diff --git a/vec.h b/vec.h new file mode 100644 index 0000000..1bb82a9 --- /dev/null +++ b/vec.h @@ -0,0 +1,55 @@ +/* vec.h: Vectors + * Created: 2026-03-10 + * Author: Aryadev Chavali + * License: See end of file + * Commentary: + Taken from https://github.com/oreodave/prick - prick_vec. + */ + +#ifndef VEC_H +#define VEC_H + +#include +#include +#include + +#define VEC_INLINE_CAPACITY 32 +#define VEC_MULT 2 + +typedef struct +{ + uint64_t size, capacity; + uint8_t not_inlined; + union + { + void *ptr; + alignas(max_align_t) uint8_t inlined[VEC_INLINE_CAPACITY]; + }; +} vec_t; + +static_assert(sizeof(vec_t) == 64, "Expected sizeof(vec_t) to be 64"); + +void vec_append(vec_t *vec, const void *const ptr, uint64_t size); +void vec_append_byte(vec_t *vec, uint8_t byte); +void *vec_data(vec_t *vec); +void vec_ensure_capacity(vec_t *vec, uint64_t capacity); +void vec_ensure_free(vec_t *vec, uint64_t size); +void vec_free(vec_t *vec); +void vec_clone(vec_t *v2, vec_t *v1); + +#define VEC_GET(VEC, INDEX, TYPE) (((TYPE *)vec_data(VEC))[INDEX]) + +#endif + +/* Copyright (C) 2026 Aryadev Chavali + + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License Version 2 for + * details. + + * You may distribute and modify this code under the terms of the GNU General + * Public License Version 2, which you should have received a copy of along with + * this program. If not, please go to . + + */