commit 5447266dfb6bc5ad7dcc8a668f4eb78b211eeee5
Author: Jake Koroman <jake@jakekoroman.com>
Date: Mon, 21 Jul 2025 19:35:16 -0400
Ready. Set. Go!
Diffstat:
A | jrk.h | | | 196 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 196 insertions(+), 0 deletions(-)
diff --git a/jrk.h b/jrk.h
@@ -0,0 +1,196 @@
+#include <stdint.h>
+
+#ifdef JRK_IMPLEMENTATION_WITH_SHORTNAMES
+#define JRK_IMPLEMENTATION
+#define JRK_SHORTNAMES
+#endif // JRK_IMPLEMENTATION_WITH_SHORTNAMES
+
+typedef int8_t i8;
+typedef int16_t i16;
+typedef int32_t i32;
+typedef int64_t i64;
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+typedef float f32;
+typedef double f64;
+
+typedef struct {
+ u8 *data;
+ u64 length;
+ u64 capacity;
+} jrk_arena;
+
+typedef struct {
+ u64 capacity;
+ u64 length;
+} jrk_array_header;
+
+/* NOTE(jake):
+ * I could use the existing jrk_array_header approach to strings
+ * but I much prefer just setting the data pointer to strings
+ * than dealing with using the hyper specific arr functions when
+ * using with strings.
+ */
+typedef struct {
+ char *data;
+ u64 length;
+} jrk_string;
+
+void *jrk_arrgrow(void*, u64, u64, u64);
+
+jrk_arena jrk_arena_create(u64);
+void *jrk__arena_push(jrk_arena*, u64);
+void jrk_arena_expand(jrk_arena*, u64);
+
+#define jrk_arrsetcap(arr,n) ((arr) = jrk_arrgrow(arr,0,sizeof(typeof(*arr)),n))
+#define jrk_arr_header(arr) ((jrk_array_header *) (arr) - 1)
+#define jrk_arrlen(arr) ((arr) ? jrk_arr_header(arr)->length : 0)
+#define jrk_arrcap(arr) ((arr) ? jrk_arr_header(arr)->capacity : 0)
+#define jrk_arrput(arr,val) (jrk_arrmaybegrow(arr,1), (arr)[jrk_arr_header(arr)->length++] = (val))
+#define jrk_arrmaybegrow(arr,n) ((!(arr) || jrk_arrlen(arr) + (n) > jrk_arrcap(arr)) ? \
+ (arr) = jrk_arrgrow(arr, n, sizeof(typeof(*arr)), 0) : 0)
+#define jrk_arrfree(arr) (free(jrk_arr_header(arr)))
+#define jrk_arrforeach(type,it,arr) for (type *it = (arr); it < (arr) + jrk_arrlen(arr); ++it)
+
+#define jrk_arena_destroy(arena) ((arena.data) ? free(arena.data) : (void) 0)
+#define jrk_arena_push_array(arena, type, n) (type *) jrk__arena_push(arena, sizeof(type) * n)
+#define jrk_arena_push_struct(arena, type) (type *) jrk__arena_push(arena, sizeof(type))
+
+#define jrk_strchop_delim_next(jrk_str,str,delim,n) jrk_strchop_delim(jrk_str.data ? \
+ str + (jrk_str.data - str) + jrk_str.length + 1 : str, \
+ delim, n)
+
+#ifdef JRK_SHORTNAMES
+#define arrput jrk_arrput
+#define arrlen jrk_arrlen
+#define arrcap jrk_arrcap
+#define arrfree jrk_arrfree
+#define arrsetcap jrk_arrsetcap
+#define arrforeach jrk_arrforeach
+
+#define arena_create jrk_arena_create
+#define arena_destroy jrk_arena_destroy
+#define arena_push_struct jrk_arena_push_struct
+#define arena_push_array jrk_arena_push_array
+#define arena_expand jrk_arena_expand
+
+#define strchop_delim jrk_strchop_delim
+#define strchop_delim_next jrk_strchop_delim_next
+#define strput jrk_strput
+#define strputn jrk_strputn
+#define string_from_parts jrk_string_from_parts
+
+#endif // JRK_SHORTNAMES
+
+#ifdef JRK_IMPLEMENTATION
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#define jrk_die(x) do { fprintf(stderr, "%s:%d: error: "x"\n", __FILE__, __LINE__); exit(69); } while(0)
+#define jrk_edie(x) do { fprintf(stderr, "%s:%d: error: "x": %s\n", __FILE__, __LINE__, strerror(errno)); exit(69); } while(0)
+
+#ifdef JRK_SHORTNAMES
+#define die jrk_die
+#define edie jrk_edie
+#endif // JRK_SHORTNAMES
+
+void *
+jrk_arrgrow(void *arr, u64 addlen, u64 elemsize, u64 min_cap)
+{
+ u64 min_len = jrk_arrlen(arr) + addlen;
+
+ if (min_len > min_cap)
+ min_cap = min_len;
+
+ if (min_cap <= jrk_arrcap(arr))
+ return arr;
+
+ if (min_cap < 2 * jrk_arrcap(arr))
+ min_cap = 2 * jrk_arrcap(arr);
+ else if (min_cap < 4)
+ min_cap = 4;
+
+ void *temp = realloc(arr ? jrk_arr_header(arr) : NULL, elemsize * min_cap + sizeof(jrk_array_header));
+ temp = (jrk_array_header *) temp + 1;
+
+ if (arr == NULL)
+ jrk_arr_header(temp)->length = 0;
+
+ jrk_arr_header(temp)->capacity = min_cap;
+ return temp;
+}
+
+jrk_arena
+jrk_arena_create(u64 n)
+{
+ jrk_arena result;
+ result.length = 0;
+ result.capacity = n;
+ result.data = malloc(result.capacity);
+ return result;
+}
+
+void *
+jrk__arena_push(jrk_arena *arena, u64 n)
+{
+ while (arena->length + n >= arena->capacity)
+ jrk_arena_expand(arena, arena->capacity * 2);
+
+ void *result = &arena->data[arena->length];
+ arena->length += n;
+ return result;
+}
+
+void
+jrk_arena_expand(jrk_arena *arena, u64 new_capacity)
+{
+ u8 *tmp = realloc(arena->data, new_capacity);
+
+ if (!tmp)
+ jrk_die("buy more ram lol");
+
+ arena->capacity = new_capacity;
+ arena->data = tmp;
+}
+
+jrk_string
+jrk_string_from_parts(char *str, u64 n)
+{
+ jrk_string result = {0};
+ result.data = str;
+ result.length = n;
+ return result;
+}
+
+jrk_string
+jrk_strchop_delim(char *str, char delim, u64 n)
+{
+ for (u64 i = 0; i < n; ++i) {
+ if (str[i] == '\0')
+ return jrk_string_from_parts(str, i);
+
+ if (str[i] == delim)
+ return jrk_string_from_parts(str, i);
+ }
+
+ return (jrk_string) {0};
+}
+
+void
+jrk_strput(jrk_string string)
+{
+ printf("%*.*s\n", (int) string.length, (int) string.length, string.data);
+}
+
+void
+jrk_strputn(jrk_string string, u64 n)
+{
+ printf("%*.*s\n", (int) n, (int) n, string.data);
+}
+
+#endif // JRK_IMPLEMENTATION