commit 493efe528d1e6f5bab55426e6304ec7173d13c9f
parent d21bdd13f2579276c34e70f187971edecda3d62a
Author: amin <dev@aminmesbah.com>
Date: Sun, 9 Jul 2023 06:40:11 +0000
Merge in the last remaining library copies
FossilOrigin-Name: 260b55b4949b90fe83b4bb79fb63f1b4ea87bcb4937b7a7eb510667830eb0e10
Diffstat:
18 files changed, 12 insertions(+), 1713 deletions(-)
diff --git a/2021/am_base.h b/2021/am_base.h
@@ -1,118 +0,0 @@
-#ifndef AM_BASE_H
-#define AM_BASE_H
-
-#if __STDC_VERSION__ < 201112L
-# error "C11 or greater required."
-#endif
-
-// context
-// https://sourceforge.net/p/predef/wiki/Home/
-#if defined(__clang__)
-# define COMPILER_CLANG 1
-#elif defined (__GNUC__)
-# define COMPILER_GCC 1
-#else
-# error "Unsupported compiler."
-#endif
-
-#if !defined(COMPILER_CLANG)
-# define COMPILER_CLANG 0
-#endif
-#if !defined(COMPILER_GCC)
-# define COMPILER_GCC 0
-#endif
-
-#if defined (__linux__)
-# define OPERATING_SYSTEM_LINUX 1
-#elif defined(_WIN32)
-# define OPERATING_SYSTEM_WINDOWS 1
-#else
-# error "Unsupported OS."
-#endif
-
-#if !defined(OPERATING_SYSTEM_LINUX)
-# define OPERATING_SYSTEM_LINUX 0
-#endif
-#if !defined(OPERATING_SYSTEM_WINDOWS)
-# define OPERATING_SYSTEM_WINDOWS 0
-#endif
-
-// compiler builtins
-#if COMPILER_CLANG || COMPILER_GCC
-# ifndef __has_builtin
-# define __has_builtin(x) 0
-# endif
-#endif
-
-#define IMPLEMENTATION_UNSIGNED_CHAR (CHAR_MIN == 0)
-
-// freestanding headers
-#include <float.h>
-#include <limits.h>
-#include <stdalign.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdnoreturn.h>
-
-// preprocessor improvement
-#define AM__STRINGIFY(S) #S
-#define AM__GLUE(A, B) A##B
-#define AM_STRINGIFY(S) AM__STRINGIFY(S)
-#define AM_GLUE(A, B) AM__GLUE((A), (B))
-
-// assert
-#define static_assert(expr) _Static_assert((expr), "")
-
-#if !defined(AM_ENABLE_ASSERT)
-# define AM_ENABLE_ASSERT 0
-#endif
-
-#if AM_ENABLE_ASSERT
-# if !defined(AM_ASSERT_FAIL)
-# if __has_builtin(__builtin_trap)
-# define AM_ASSERT_FAIL(expr, file, line, func) __builtin_trap()
-# else
-# error "Must define implementation of AM_ASSERT_FAIL(expr, file, line, func)."
-# endif
-# endif
-# define assert(x) ((void)((x) || (AM_ASSERT_FAIL(AM_STRINGIFY(x), __FILE__, __LINE__, __func__),0)))
-#else
-# define assert(c) ((void)0)
-#endif
-
-#define AM_UNREACHABLE assert(false && "Unreachable code reached")
-
-// utility macros
-#define ALIGN_UP_POW_2(x, p) (((x) + (p) - 1) & ~((p) - (1)))
-#define ALIGN_DOWN_POW_2(x, p) ((x) & ~((p) - 1))
-#define ARRAY_COUNT(a) (sizeof(a)/sizeof(*(a)))
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#define CLAMP(a, x, b) (((x) < (a)) ? (a) : (((b) < (x)) ? (b) : (x)))
-#define CLAMP_TOP(a, b) MIN((a), (b))
-#define CLAMP_BOT(a, b) MAX((a), (b))
-#define UNUSED(p) (void)(p)
-
-// basic types
-typedef int8_t s8;
-typedef int16_t s16;
-typedef int32_t s32;
-typedef int64_t s64;
-typedef uint8_t u8;
-typedef uint16_t u16;
-typedef uint32_t u32;
-typedef uint64_t u64;
-typedef size_t usz;
-typedef float f32;
-typedef double f64;
-
-#define global static
-#define local_persist static
-#define internal static
-
-// sanity checks
-static_assert(CHAR_BIT == 8);
-
-#endif // AM_BASE_H
diff --git a/2021/am_list.h b/2021/am_list.h
@@ -1,233 +0,0 @@
-#ifndef AM_LIST_H
-#define AM_LIST_H
-
-#define DLL_APPEND_NP(f, l, n, next, prev) \
- ((f) == NULL \
- ? ((f) = (l) = (n) \
- , (f)->prev = (n)->next = NULL) \
- : ((n)->prev = (l) \
- , (l)->next = (n) \
- , (l) = (n) \
- , (n)->next = NULL))
-
-#define DLL_REMOVE_NP(f, l, n, next, prev) \
- ((f) == (l) && (f) == (n) \
- ? ((f) = (l) = NULL) \
- : ((f) == (n) \
- ? ((f) = (f)->next \
- , (f)->prev = NULL) \
- : ((l) == (n) \
- ? ((l) = (l)->prev \
- , (l)->next = NULL) \
- : ((n)->prev->next = (n)->next \
- , (n)->next->prev = (n)->prev))))
-
-#define SLL_QUEUE_PUSH_N(f, l, n, next) \
- ((f) == NULL \
- ? ((f) = (l) = (n)) \
- : ((l)->next = (n) \
- , (l) = (n) \
- , (n)->next = NULL))
-
-#define SLL_QUEUE_PUSH_FRONT_N(f, l, n, next) \
- ((f) == NULL \
- ? ((f) = (l) = (n) \
- , (n)->next = NULL) \
- : ((n)->next = (f) \
- , (f) = (n)))
-
-// TODO: It's maybe somewhat surprising to the user that these pop functions
-// don't return the popped node.
-#define SLL_QUEUE_POP_N(f, l, next) \
- ((f) == (l) \
- ? ((f) = (l) = NULL) \
- : ((f) = (f)->next))
-
-
-#define SLL_STACK_PUSH_N(f, n, next) ((n)->next = (f), (f) = (n))
-
-#define SLL_STACK_POP_N(f, next) \
- ((f) == NULL \
- ? 0 \
- : ((f) = (f)->next))
-
-#define DLL_APPEND(f, l, n) DLL_APPEND_NP((f), (l), (n), next, prev)
-#define DLL_PREPEND(f, l, n) DLL_APPEND_NP((l), (f), (n), prev, next)
-#define DLL_REMOVE(f, l, n) DLL_REMOVE_NP((f), (l), (n), next, prev)
-
-#define SLL_QUEUE_PUSH(f, l, n) SLL_QUEUE_PUSH_N((f), (l), (n), next)
-#define SLL_QUEUE_PUSH_FRONT(f, l, n) SLL_QUEUE_PUSH_FRONT_N((f), (l), (n), next)
-#define SLL_QUEUE_POP(f, l) SLL_QUEUE_POP_N((f), (l), next)
-
-#define SLL_STACK_PUSH(f, n) SLL_STACK_PUSH_N((f), (n), next)
-#define SLL_STACK_POP(f) SLL_STACK_POP_N((f), next)
-
-#if defined(AM_INCLUDE_TESTS)
-typedef struct TestNode TestNode;
-struct TestNode {
- TestNode *next;
- TestNode *prev;
- s32 val;
-};
-
-internal void am_list_test(void) {
- TestNode nodes[10] = {0};
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- nodes[i].val = i;
- }
-
- {
- TestNode *first = NULL;
- TestNode *last = NULL;
-
- printf("dll append and remove from front\n");
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- DLL_APPEND(first, last, &nodes[i]);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf(" <|> ");
- for (TestNode *n = last; n; n = n->prev) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
-
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- DLL_REMOVE(first, last, &nodes[i]);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf(" <|> ");
- for (TestNode *n = last; n; n = n->prev) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
-
- printf("dll prepend and remove from back\n");
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- DLL_PREPEND(first, last, &nodes[i]);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf(" <|> ");
- for (TestNode *n = last; n; n = n->prev) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
-
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- DLL_REMOVE(first, last, &nodes[i]);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf(" <|> ");
- for (TestNode *n = last; n; n = n->prev) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
-
- printf("dll append and remove from middle\n");
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- DLL_APPEND(first, last, &nodes[i]);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf(" <|> ");
- for (TestNode *n = last; n; n = n->prev) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
-
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- DLL_REMOVE(first, last, &nodes[(i + (ARRAY_COUNT(nodes) / 2)) % ARRAY_COUNT(nodes)]);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf(" <|> ");
- for (TestNode *n = last; n; n = n->prev) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
- }
-
- {
- TestNode *first = NULL;
- TestNode *last = NULL;
-
- printf("sll queue push and pop\n");
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- SLL_QUEUE_PUSH(first, last, &nodes[i]);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
-
- while (first) {
- SLL_QUEUE_POP(first, last);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
-
- printf("sll queue push front and pop\n");
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- SLL_QUEUE_PUSH_FRONT(first, last, &nodes[i]);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
-
- while (first) {
- SLL_QUEUE_POP(first, last);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
- }
-
- {
- TestNode *first = NULL;
-
- printf("sll stack push and pop\n");
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- SLL_STACK_PUSH(first, &nodes[i]);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
-
- while (first) {
- SLL_STACK_POP(first);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
- }
-}
-#endif // defined(AM_INCLUDE_TESTS)
-
-#endif // AM_LIST_H
diff --git a/2021/am_memory.h b/2021/am_memory.h
@@ -1,178 +0,0 @@
-#ifndef AM_MEMORY_H
-#define AM_MEMORY_H
-
-#define MEM_KIB(b) ((u64)(b) << 10)
-#define MEM_MIB(b) ((u64)(b) << 20)
-#define MEM_GIB(b) ((u64)(b) << 30)
-
-#define AM_MEM_RESERVE_FN(name) void *(name)(void *ctx, u64 size)
-typedef AM_MEM_RESERVE_FN(am_mem_reserve_fn);
-
-#define AM_MEM_CHANGE_FN(name) void (name)(void *ctx, void *ptr, u64 size)
-typedef AM_MEM_CHANGE_FN(am_mem_change_fn);
-
-typedef struct {
- am_mem_reserve_fn* reserve;
- am_mem_change_fn* commit;
- am_mem_change_fn* decommit;
- am_mem_change_fn* release;
- void *ctx;
-} BaseAllocator;
-
-#define AM_MEM_ARENA_COMMIT_BLOCK_SIZE MEM_MIB(64)
-#define AM_MEM_ARENA_DEFAULT_RESERVE_SIZE MEM_GIB(1)
-
-typedef struct {
- BaseAllocator *base;
- u8 *mem;
- u64 cap;
- u64 pos;
- u64 commit_pos;
-} MemArena;
-
-internal AM_MEM_CHANGE_FN(am_mem_change_noop) {
- UNUSED(ctx);
- UNUSED(ptr);
- UNUSED(size);
-}
-
-internal AM_MEM_RESERVE_FN(am_mem_reserve_malloc) {
- UNUSED(ctx);
- return malloc(size);
-}
-
-internal AM_MEM_CHANGE_FN(am_mem_release_malloc) {
- UNUSED(ctx);
- UNUSED(size);
- free(ptr);
-}
-
-internal BaseAllocator *am_mem_base_allocator_malloc(void) {
- local_persist BaseAllocator b;
- if (!b.reserve) {
- b = (BaseAllocator) {
- .reserve = am_mem_reserve_malloc,
- .commit = am_mem_change_noop,
- .decommit = am_mem_change_noop,
- .release = am_mem_release_malloc,
- };
- }
- return &b;
-}
-
-internal MemArena am_mem_arena_create_reserve(BaseAllocator *base, u64 reserve_size) {
- MemArena a = {
- .base = base,
- };
- a.mem = a.base->reserve(a.base->ctx, reserve_size);
- a.cap = reserve_size;
- return a;
-}
-
-internal MemArena am_mem_arena_create(BaseAllocator *base) {
- return am_mem_arena_create_reserve(base, AM_MEM_ARENA_DEFAULT_RESERVE_SIZE);
-}
-
-internal void *am_mem_arena_push(MemArena *a, u64 size) {
- void *result = NULL;
- if (a->mem + size <= a->mem + a->cap) {
- result = a->mem + a->pos;
- a->pos += size;
-
- if (a->pos > a->commit_pos) {
- u64 aligned = ALIGN_UP_POW_2(a->pos, AM_MEM_ARENA_COMMIT_BLOCK_SIZE);
- u64 next_commit_pos = CLAMP_TOP(aligned, a->cap);
- u64 commit_size = next_commit_pos - a->commit_pos;
- a->base->commit(a->base->ctx, a->mem + a->commit_pos, commit_size);
- a->commit_pos = next_commit_pos;
- }
- }
- return result;
-}
-
-#define AM_MEM_ARENA_PUSH_ARRAY(arena, T, count) (am_mem_arena_push((arena), sizeof(T) * (count)))
-
-internal void am_mem_arena_pop_to(MemArena *a, u64 pos) {
- if (pos < a->pos) {
- a->pos = pos;
-
- u64 aligned = ALIGN_UP_POW_2(a->pos, AM_MEM_ARENA_COMMIT_BLOCK_SIZE);
- u64 next_commit_pos = CLAMP_TOP(aligned, a->cap);
- if (next_commit_pos < a->commit_pos) {
- u64 decommit_size = a->commit_pos - next_commit_pos;
- a->base->decommit(a->base->ctx, a->mem + a->commit_pos, decommit_size);
- a->commit_pos = next_commit_pos;
- }
- }
-}
-
-internal void am_mem_arena_release(MemArena *a) {
- a->base->release(a->base->ctx, a->mem, a->cap);
- *a = (MemArena){0};
-}
-
-// TODO: SIMD
-internal void am_mem_copy(void *dst, void *src, u64 size) {
- for (u64 i = 0; i < size; i++) {
- ((u8 *)dst)[i] = ((u8 *)src)[i];
- }
-}
-
-internal bool am_mem_equal(void *dst, void *src, u64 size) {
- for (u64 i = 0; i < size; i++) {
- if (((u8 *)dst)[i] != ((u8 *)src)[i]) {
- return false;
- }
- }
- return true;
-}
-
-#if defined(AM_INCLUDE_TESTS)
-internal void am_memory_test(void) {
- assert(MEM_KIB(10) == 10240);
- assert(MEM_MIB(10) == 10485760);
- assert(MEM_GIB(10) == 10737418240);
-
- {
- BaseAllocator *a = am_mem_base_allocator_malloc();
- u64 num_test_ints = 10;
- s32 *int_buf = a->reserve(NULL, num_test_ints * sizeof(s32));
- assert(int_buf);
- a->release(NULL, int_buf, 0);
- }
-
- {
- MemArena a = am_mem_arena_create(am_mem_base_allocator_malloc());
- am_mem_arena_push(&a, 1020);
- assert(a.pos == 1020);
- u64 p = a.pos;
- u64 cp = a.commit_pos;
-
- AM_MEM_ARENA_PUSH_ARRAY(&a, u8, a.cap - a.pos);
- assert(a.pos == a.cap);
- assert(a.commit_pos == a.cap);
-
- am_mem_arena_pop_to(&a, p);
- assert(a.pos == p);
- assert(a.commit_pos == cp);
-
- am_mem_arena_release(&a);
- assert(a.pos == 0);
- assert(a.commit_pos == 0);
- assert(a.mem == NULL);
- }
-
- {
- u8 src[10] = {0};
- u8 dst[10] = {0};
- for (u64 i = 0; i < ARRAY_COUNT(src); i++) {
- src[i] = i;
- }
-
- am_mem_copy(dst, src, ARRAY_COUNT(dst));
- assert(am_mem_equal(dst, src, ARRAY_COUNT(dst)));
- }
-}
-#endif // defined(AM_INCLUDE_TESTS)
-
-#endif // AM_MEMORY_H
diff --git a/2021/am_string.h b/2021/am_string.h
@@ -1,257 +0,0 @@
-#ifndef AM_STRING_H
-#define AM_STRING_H
-
-#ifndef AM_MEMORY_H
- #error "am_memory.h is required"
-#endif
-#ifndef AM_LIST_H
- #error "am_list.h is required"
-#endif
-
-typedef struct {
- usz size;
- u8 *str;
-} Str;
-
-typedef struct StrListNode StrListNode;
-struct StrListNode {
- StrListNode *next;
- Str s;
-};
-
-typedef struct {
- StrListNode *first;
- StrListNode *last;
- u64 node_count;
- u64 total_size;
-} StrList;
-
-#define AM_STR_LIT(s) (Str) { .str = (u8 *)(s), .size = sizeof(s) - 1, }
-#define AM_STR_EXPAND(s) (s32)((s).size), ((s).str)
-
-internal usz am_cstr_len(char *cstr) {
- usz len = 0;
- while (cstr && *cstr != '\0') {
- len++;
- cstr++;
- }
- return len;
-}
-
-internal Str am_str(u8 *str, usz size) {
- return (Str) { .size = size, .str = str, };
-}
-
-internal Str am_str_from_range(u8 *start, u8 *opl) {
- assert(start < opl);
- return am_str(start, opl - start);
-}
-
-internal Str am_str_from_cstr(char *cstr, usz len) {
- return am_str((u8 *)cstr, len);
-}
-
-// TODO: Use string interning
-internal bool am_str_eq(Str s1, Str s2) {
- if (s1.size != s2.size) {
- return false;
- }
-
- for (usz i = 0; i < s1.size; i++) {
- if (s1.str[i] != s2.str[i]) {
- return false;
- }
- }
-
- return true;
-}
-
-internal bool am_cstr_eq(char *cstr1, char *cstr2) {
- usz len1 = am_cstr_len(cstr1);
- usz len2 = am_cstr_len(cstr2);
- return am_str_eq(am_str_from_cstr(cstr1, len1), am_str_from_cstr(cstr2, len2));
-}
-
-internal Str am_str_line(Str s, u8 *cursor) {
- u8 *opl = s.str + s.size;
-
- assert(cursor >= s.str && cursor < opl);
-
- u8 *end = cursor;
- while (end < opl) {
- if (*end == '\n') {
- break;
- }
- end++;
- }
-
- u8 *beginning = cursor - (*cursor == '\n');
- while (beginning >= s.str) {
- if (*beginning == '\n') {
- beginning++;
- break;
- }
- beginning--;
- }
-
- return am_str_from_range(beginning, end);
-}
-
-internal bool am_str_contains(Str s, char c) {
- for (usz i = 0; i < s.size; i++) {
- if (s.str[i] == c) {
- return true;
- }
- }
- return false;
-}
-
-internal bool am_cstr_contains(char *s, usz len, char c) {
- return am_str_contains(am_str_from_cstr(s, len), c);
-}
-
-internal bool am_str_cstr_eq(Str s, char *cstr) {
- return am_str_eq(s, am_str_from_cstr(cstr, am_cstr_len(cstr)));
-}
-
-internal void am_str_list_append(MemArena *arena, StrList *list, Str s) {
- StrListNode *node = am_mem_arena_push(arena, sizeof(StrListNode));
- *node = (StrListNode) {
- .s = s,
- };
- SLL_QUEUE_PUSH(list->first, list->last, node);
- list->node_count += 1;
- list->total_size += s.size;
-}
-
-typedef struct {
- Str pre;
- Str mid;
- Str post;
-} StringJoinOptions;
-
-internal Str am_str_join(MemArena *arena, StrList *list, StringJoinOptions *options) {
- StringJoinOptions join;
- if (options) {
- join = *options;
- } else {
- join = (StringJoinOptions){0};
- }
-
- u64 total_size = list->total_size
- + join.pre.size
- + (join.mid.size * (list->node_count - 1))
- + join.post.size;
-
- Str s= {
- .str = AM_MEM_ARENA_PUSH_ARRAY(arena, u8, total_size),
- .size = total_size,
- };
-
- u8 *p = s.str;
- am_mem_copy(p, join.pre.str, join.pre.size);
- p += join.pre.size;
-
- bool is_mid = false;
- for (StrListNode *n = list->first; n; n = n->next) {
- if (is_mid) {
- am_mem_copy(p, join.mid.str, join.mid.size);
- p += join.mid.size;
- }
-
- am_mem_copy(p, n->s.str, n->s.size);
- p += n->s.size;
-
- is_mid = true;
- }
-
- am_mem_copy(p, join.post.str, join.post.size);
- p += join.post.size;
-
- return s;
-}
-
-internal StrList am_str_split(MemArena *arena, Str s, u8 *split_chars, u64 split_char_count) {
- StrList list = {0};
-
- u8 *cursor = s.str;
- u8 *split_beginning = cursor;
- u8 *opl = s.str + s.size;
- while (cursor < opl) {
- bool split_byte = false;
- for (u64 i = 0; i < split_char_count; i++) {
- if (split_chars[i] == *cursor) {
- split_byte = true;
- break;
- }
- }
-
- if (split_byte) {
- if (split_beginning < cursor) {
- am_str_list_append(arena, &list, am_str_from_range(split_beginning, cursor));
- }
- split_beginning = cursor + 1;
- }
- cursor++;
- }
-
- if (split_beginning < cursor) {
- am_str_list_append(arena, &list, am_str_from_range(split_beginning, cursor));
- }
-
- return list;
-}
-
-#if defined(AM_INCLUDE_TESTS)
-internal void am_string_test(void) {
- assert(am_cstr_len("abcdefg") == 7);
- assert(am_cstr_len("") == 0);
- assert(am_cstr_len("\0") == 0);
- assert(am_cstr_eq("", ""));
- assert(am_cstr_eq("\0", "\0"));
- assert(am_cstr_eq("abc", "abc"));
- assert(!am_cstr_eq("ABC", "abc"));
- assert(!am_cstr_eq("", " "));
- assert(!am_cstr_eq("abc", "abcde"));
- assert(!am_str_cstr_eq(AM_STR_LIT("abcd"), "abc"));
- assert(am_str_cstr_eq(AM_STR_LIT("abc"), "abc"));
- assert(am_cstr_contains("abc", 3, 'c'));
- assert(am_cstr_contains("a c", 3, ' '));
- assert(am_cstr_contains("", 1, '\0'));
- assert(!am_cstr_contains("abc", 3, 'z'));
- assert(!am_cstr_contains("", 0, 'z'));
- assert(!am_cstr_contains("", 0, '\0'));
- assert(am_cstr_contains("https://www.example.com", 23, '/'));
-
- {
- StrList l = {0};
- MemArena a = am_mem_arena_create(am_mem_base_allocator_malloc());
- Str strings[] = {
- AM_STR_LIT("one"),
- AM_STR_LIT("two"),
- AM_STR_LIT("three"),
- };
-
- for (u64 i = 0; i < ARRAY_COUNT(strings); i++) {
- am_str_list_append(&a, &l, strings[i]);
- }
-
- Str joined = am_str_join(&a, &l, &(StringJoinOptions){
- .pre = AM_STR_LIT("Joined: '"),
- .mid = AM_STR_LIT(", "),
- .post = AM_STR_LIT("'."),
- });
-
- printf("%.*s\n", AM_STR_EXPAND(joined));
-
- StrList split = am_str_split(&a, AM_STR_LIT(", one, two, three, "), (u8 *)", ", 2);
-
- for (StrListNode *n = split.first; n; n = n->next) {
- printf("split: '%.*s'\n", AM_STR_EXPAND(n->s));
- }
- am_mem_arena_release(&a);
- }
-}
-#endif // defined(AM_INCLUDE_TESTS)
-
-#endif // AM_STRING_H
diff --git a/2021/day01_01.c b/2021/day01_01.c
@@ -7,7 +7,7 @@ if [ "$input" -nt "$output" ];
then
mkdir --parents "$outdir" || exit
echo "Building ${output}." || exit
- clang -std=c11 -Wall -Wextra -pedantic -Wno-unused-function "$input" -o "$output" || exit
+ clang -std=c11 -Wall -Wextra -pedantic -Wno-unused-function -I../../amlibs/ "$input" -o "$output" || exit
fi
if [ "$1" = "-r" ];
then
diff --git a/2021/day01_02.c b/2021/day01_02.c
@@ -7,7 +7,7 @@ if [ "$input" -nt "$output" ];
then
mkdir --parents "$outdir" || exit
echo "Building ${output}." || exit
- clang -std=c11 -Wall -Wextra -pedantic -Wno-unused-function "$input" -o "$output" || exit
+ clang -std=c11 -Wall -Wextra -pedantic -Wno-unused-function -I../../amlibs/ "$input" -o "$output" || exit
fi
if [ "$1" = "-r" ];
then
diff --git a/2021/day02_01.c b/2021/day02_01.c
@@ -7,7 +7,7 @@ if [ "$input" -nt "$output" ];
then
mkdir --parents "$outdir" || exit
echo "Building ${output}." || exit
- clang -std=c11 -Wall -Wextra -pedantic -Wno-unused-function "$input" -o "$output" || exit
+ clang -std=c11 -Wall -Wextra -pedantic -Wno-unused-function -I../../amlibs/ "$input" -o "$output" || exit
fi
if [ "$1" = "-r" ];
then
diff --git a/2021/day02_02.c b/2021/day02_02.c
@@ -7,7 +7,7 @@ if [ "$input" -nt "$output" ];
then
mkdir --parents "$outdir" || exit
echo "Building ${output}." || exit
- clang -std=c11 -Wall -Wextra -pedantic -Wno-unused-function "$input" -o "$output" || exit
+ clang -std=c11 -Wall -Wextra -pedantic -Wno-unused-function -I../../amlibs/ "$input" -o "$output" || exit
fi
if [ "$1" = "-r" ];
then
diff --git a/2021/day03_01.c b/2021/day03_01.c
@@ -7,7 +7,7 @@ if [ "$input" -nt "$output" ];
then
mkdir --parents "$outdir" || exit
echo "Building ${output}." || exit
- clang -std=c11 -Wall -Wextra -pedantic -Wno-unused-function "$input" -o "$output" || exit
+ clang -std=c11 -Wall -Wextra -pedantic -Wno-unused-function -I../../amlibs/ "$input" -o "$output" || exit
fi
if [ "$1" = "-r" ];
then
diff --git a/2021/day03_02.c b/2021/day03_02.c
@@ -7,7 +7,7 @@ if [ "$input" -nt "$output" ];
then
mkdir --parents "$outdir" || exit
echo "Building ${output}." || exit
- clang -std=c11 -Wall -Wextra -pedantic -Wno-unused-function "$input" -o "$output" || exit
+ clang -std=c11 -Wall -Wextra -pedantic -Wno-unused-function -I../../amlibs/ "$input" -o "$output" || exit
fi
if [ "$1" = "-r" ];
then
diff --git a/2021/day04_01.c b/2021/day04_01.c
@@ -7,7 +7,7 @@ if [ "$input" -nt "$output" ];
then
mkdir --parents "$outdir" || exit
echo "Building ${output}." || exit
- clang -std=c11 -Wall -Wextra -pedantic -Wno-unused-function "$input" -o "$output" || exit
+ clang -std=c11 -Wall -Wextra -pedantic -Wno-unused-function -I../../amlibs/ "$input" -o "$output" || exit
fi
if [ "$1" = "-r" ];
then
@@ -82,6 +82,7 @@ int main(void) {
Str input = open_file(&a, "day04_input.txt");
StrList split_data = am_str_split(&a, input, (u8 *)"\n ", 2);
+ am_str_list_discard_empty(&split_data);
StrList split_first_line = am_str_split(&a, split_data.first->s, (u8 *)",", 1);
u64 drawn_number_count = split_first_line.node_count;
diff --git a/2021/day04_02.c b/2021/day04_02.c
@@ -7,7 +7,7 @@ if [ "$input" -nt "$output" ];
then
mkdir --parents "$outdir" || exit
echo "Building ${output}." || exit
- clang -std=c11 -Wall -Wextra -pedantic -Wno-unused-function "$input" -o "$output" || exit
+ clang -std=c11 -Wall -Wextra -pedantic -Wno-unused-function -I../../amlibs/ "$input" -o "$output" || exit
fi
if [ "$1" = "-r" ];
then
@@ -82,6 +82,7 @@ int main(void) {
Str input = open_file(&a, "day04_input.txt");
StrList split_data = am_str_split(&a, input, (u8 *)"\n ", 2);
+ am_str_list_discard_empty(&split_data);
StrList split_first_line = am_str_split(&a, split_data.first->s, (u8 *)",", 1);
u64 drawn_number_count = split_first_line.node_count;
diff --git a/2022/am_base.h b/2022/am_base.h
@@ -1,118 +0,0 @@
-#ifndef AM_BASE_H
-#define AM_BASE_H
-
-#if __STDC_VERSION__ < 201112L
-# error "C11 or greater required."
-#endif
-
-// context
-// https://sourceforge.net/p/predef/wiki/Home/
-#if defined(__clang__)
-# define COMPILER_CLANG 1
-#elif defined (__GNUC__)
-# define COMPILER_GCC 1
-#else
-# error "Unsupported compiler."
-#endif
-
-#if !defined(COMPILER_CLANG)
-# define COMPILER_CLANG 0
-#endif
-#if !defined(COMPILER_GCC)
-# define COMPILER_GCC 0
-#endif
-
-#if defined (__linux__)
-# define OPERATING_SYSTEM_LINUX 1
-#elif defined(_WIN32)
-# define OPERATING_SYSTEM_WINDOWS 1
-#else
-# error "Unsupported OS."
-#endif
-
-#if !defined(OPERATING_SYSTEM_LINUX)
-# define OPERATING_SYSTEM_LINUX 0
-#endif
-#if !defined(OPERATING_SYSTEM_WINDOWS)
-# define OPERATING_SYSTEM_WINDOWS 0
-#endif
-
-// compiler builtins
-#if COMPILER_CLANG || COMPILER_GCC
-# ifndef __has_builtin
-# define __has_builtin(x) 0
-# endif
-#endif
-
-#define IMPLEMENTATION_UNSIGNED_CHAR (CHAR_MIN == 0)
-
-// freestanding headers
-#include <float.h>
-#include <limits.h>
-#include <stdalign.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdnoreturn.h>
-
-// preprocessor improvement
-#define AM__STRINGIFY(S) #S
-#define AM__GLUE(A, B) A##B
-#define AM_STRINGIFY(S) AM__STRINGIFY(S)
-#define AM_GLUE(A, B) AM__GLUE((A), (B))
-
-// assert
-#define static_assert(expr) _Static_assert((expr), "")
-
-#if !defined(AM_ENABLE_ASSERT)
-# define AM_ENABLE_ASSERT 0
-#endif
-
-#if AM_ENABLE_ASSERT
-# if !defined(AM_ASSERT_FAIL)
-# if __has_builtin(__builtin_trap)
-# define AM_ASSERT_FAIL(expr, file, line, func) __builtin_trap()
-# else
-# error "Must define implementation of AM_ASSERT_FAIL(expr, file, line, func)."
-# endif
-# endif
-# define assert(x) ((void)((x) || (AM_ASSERT_FAIL(AM_STRINGIFY(x), __FILE__, __LINE__, __func__),0)))
-#else
-# define assert(c) ((void)0)
-#endif
-
-#define AM_UNREACHABLE assert(false && "Unreachable code reached")
-
-// utility macros
-#define ALIGN_UP_POW_2(x, p) (((x) + (p) - 1) & ~((p) - (1)))
-#define ALIGN_DOWN_POW_2(x, p) ((x) & ~((p) - 1))
-#define ARRAY_COUNT(a) (sizeof(a)/sizeof(*(a)))
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#define CLAMP(a, x, b) (((x) < (a)) ? (a) : (((b) < (x)) ? (b) : (x)))
-#define CLAMP_TOP(a, b) MIN((a), (b))
-#define CLAMP_BOT(a, b) MAX((a), (b))
-#define UNUSED(p) (void)(p)
-
-// basic types
-typedef int8_t s8;
-typedef int16_t s16;
-typedef int32_t s32;
-typedef int64_t s64;
-typedef uint8_t u8;
-typedef uint16_t u16;
-typedef uint32_t u32;
-typedef uint64_t u64;
-typedef size_t usz;
-typedef float f32;
-typedef double f64;
-
-#define global static
-#define local_persist static
-#define internal static
-
-// sanity checks
-static_assert(CHAR_BIT == 8);
-
-#endif // AM_BASE_H
diff --git a/2022/am_list.h b/2022/am_list.h
@@ -1,233 +0,0 @@
-#ifndef AM_LIST_H
-#define AM_LIST_H
-
-#define DLL_APPEND_NP(f, l, n, next, prev) \
- ((f) == NULL \
- ? ((f) = (l) = (n) \
- , (f)->prev = (n)->next = NULL) \
- : ((n)->prev = (l) \
- , (l)->next = (n) \
- , (l) = (n) \
- , (n)->next = NULL))
-
-#define DLL_REMOVE_NP(f, l, n, next, prev) \
- ((f) == (l) && (f) == (n) \
- ? ((f) = (l) = NULL) \
- : ((f) == (n) \
- ? ((f) = (f)->next \
- , (f)->prev = NULL) \
- : ((l) == (n) \
- ? ((l) = (l)->prev \
- , (l)->next = NULL) \
- : ((n)->prev->next = (n)->next \
- , (n)->next->prev = (n)->prev))))
-
-#define SLL_QUEUE_PUSH_N(f, l, n, next) \
- ((f) == NULL \
- ? ((f) = (l) = (n)) \
- : ((l)->next = (n) \
- , (l) = (n) \
- , (n)->next = NULL))
-
-#define SLL_QUEUE_PUSH_FRONT_N(f, l, n, next) \
- ((f) == NULL \
- ? ((f) = (l) = (n) \
- , (n)->next = NULL) \
- : ((n)->next = (f) \
- , (f) = (n)))
-
-// TODO: It's maybe somewhat surprising to the user that these pop functions
-// don't return the popped node.
-#define SLL_QUEUE_POP_N(f, l, next) \
- ((f) == (l) \
- ? ((f) = (l) = NULL) \
- : ((f) = (f)->next))
-
-
-#define SLL_STACK_PUSH_N(f, n, next) ((n)->next = (f), (f) = (n))
-
-#define SLL_STACK_POP_N(f, next) \
- ((f) == NULL \
- ? 0 \
- : ((f) = (f)->next))
-
-#define DLL_APPEND(f, l, n) DLL_APPEND_NP((f), (l), (n), next, prev)
-#define DLL_PREPEND(f, l, n) DLL_APPEND_NP((l), (f), (n), prev, next)
-#define DLL_REMOVE(f, l, n) DLL_REMOVE_NP((f), (l), (n), next, prev)
-
-#define SLL_QUEUE_PUSH(f, l, n) SLL_QUEUE_PUSH_N((f), (l), (n), next)
-#define SLL_QUEUE_PUSH_FRONT(f, l, n) SLL_QUEUE_PUSH_FRONT_N((f), (l), (n), next)
-#define SLL_QUEUE_POP(f, l) SLL_QUEUE_POP_N((f), (l), next)
-
-#define SLL_STACK_PUSH(f, n) SLL_STACK_PUSH_N((f), (n), next)
-#define SLL_STACK_POP(f) SLL_STACK_POP_N((f), next)
-
-#ifdef AM_LIST_TESTS
-typedef struct TestNode TestNode;
-struct TestNode {
- TestNode *next;
- TestNode *prev;
- s32 val;
-};
-
-internal void am_list_test(void) {
- TestNode nodes[10] = {0};
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- nodes[i].val = i;
- }
-
- {
- TestNode *first = NULL;
- TestNode *last = NULL;
-
- printf("dll append and remove from front\n");
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- DLL_APPEND(first, last, &nodes[i]);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf(" <|> ");
- for (TestNode *n = last; n; n = n->prev) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
-
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- DLL_REMOVE(first, last, &nodes[i]);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf(" <|> ");
- for (TestNode *n = last; n; n = n->prev) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
-
- printf("dll prepend and remove from back\n");
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- DLL_PREPEND(first, last, &nodes[i]);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf(" <|> ");
- for (TestNode *n = last; n; n = n->prev) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
-
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- DLL_REMOVE(first, last, &nodes[i]);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf(" <|> ");
- for (TestNode *n = last; n; n = n->prev) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
-
- printf("dll append and remove from middle\n");
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- DLL_APPEND(first, last, &nodes[i]);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf(" <|> ");
- for (TestNode *n = last; n; n = n->prev) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
-
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- DLL_REMOVE(first, last, &nodes[(i + (ARRAY_COUNT(nodes) / 2)) % ARRAY_COUNT(nodes)]);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf(" <|> ");
- for (TestNode *n = last; n; n = n->prev) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
- }
-
- {
- TestNode *first = NULL;
- TestNode *last = NULL;
-
- printf("sll queue push and pop\n");
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- SLL_QUEUE_PUSH(first, last, &nodes[i]);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
-
- while (first) {
- SLL_QUEUE_POP(first, last);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
-
- printf("sll queue push front and pop\n");
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- SLL_QUEUE_PUSH_FRONT(first, last, &nodes[i]);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
-
- while (first) {
- SLL_QUEUE_POP(first, last);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
- }
-
- {
- TestNode *first = NULL;
-
- printf("sll stack push and pop\n");
- for (size_t i = 0; i < ARRAY_COUNT(nodes); i++) {
- SLL_STACK_PUSH(first, &nodes[i]);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
-
- while (first) {
- SLL_STACK_POP(first);
- printf("[");
- for (TestNode *n = first; n; n = n->next) {
- printf(" %i ", n->val);
- }
- printf("]\n");
- }
- }
-}
-#endif // AM_LIST_TESTS
-
-#endif // AM_LIST_H
diff --git a/2022/am_memory.h b/2022/am_memory.h
@@ -1,185 +0,0 @@
-#ifndef AM_MEMORY_H
-#define AM_MEMORY_H
-
-#define MEM_KIB(b) ((u64)(b) << 10)
-#define MEM_MIB(b) ((u64)(b) << 20)
-#define MEM_GIB(b) ((u64)(b) << 30)
-
-#define AM_MEM_RESERVE_FN(name) void *(name)(void *ctx, u64 size)
-typedef AM_MEM_RESERVE_FN(am_mem_reserve_fn);
-
-#define AM_MEM_CHANGE_FN(name) void (name)(void *ctx, void *ptr, u64 size)
-typedef AM_MEM_CHANGE_FN(am_mem_change_fn);
-
-typedef struct {
- am_mem_reserve_fn* reserve;
- am_mem_change_fn* commit;
- am_mem_change_fn* decommit;
- am_mem_change_fn* release;
- void *ctx;
-} BaseAllocator;
-
-#define AM_MEM_ARENA_COMMIT_BLOCK_SIZE MEM_MIB(64)
-#define AM_MEM_ARENA_DEFAULT_RESERVE_SIZE MEM_GIB(1)
-
-typedef struct {
- BaseAllocator *base;
- u8 *mem;
- u64 cap;
- u64 pos;
- u64 commit_pos;
-} MemArena;
-
-internal AM_MEM_CHANGE_FN(am_mem_change_noop) {
- UNUSED(ctx);
- UNUSED(ptr);
- UNUSED(size);
-}
-
-internal AM_MEM_RESERVE_FN(am_mem_reserve_malloc) {
- UNUSED(ctx);
- return malloc(size);
-}
-
-internal AM_MEM_CHANGE_FN(am_mem_release_malloc) {
- UNUSED(ctx);
- UNUSED(size);
- free(ptr);
-}
-
-internal BaseAllocator *am_mem_base_allocator_malloc(void) {
- local_persist BaseAllocator b;
- if (!b.reserve) {
- b = (BaseAllocator) {
- .reserve = am_mem_reserve_malloc,
- .commit = am_mem_change_noop,
- .decommit = am_mem_change_noop,
- .release = am_mem_release_malloc,
- };
- }
- return &b;
-}
-
-internal MemArena am_mem_arena_create_reserve(BaseAllocator *base, u64 reserve_size) {
- MemArena a = {
- .base = base,
- };
- a.mem = a.base->reserve(a.base->ctx, reserve_size);
- a.cap = reserve_size;
- return a;
-}
-
-internal MemArena am_mem_arena_create(BaseAllocator *base) {
- return am_mem_arena_create_reserve(base, AM_MEM_ARENA_DEFAULT_RESERVE_SIZE);
-}
-
-internal void *am_mem_arena_push(MemArena *a, u64 size) {
- void *result = NULL;
- if (a->mem + size <= a->mem + a->cap) {
- result = a->mem + a->pos;
- a->pos += size;
-
- if (a->pos > a->commit_pos) {
- u64 aligned = ALIGN_UP_POW_2(a->pos, AM_MEM_ARENA_COMMIT_BLOCK_SIZE);
- u64 next_commit_pos = CLAMP_TOP(aligned, a->cap);
- u64 commit_size = next_commit_pos - a->commit_pos;
- a->base->commit(a->base->ctx, a->mem + a->commit_pos, commit_size);
- a->commit_pos = next_commit_pos;
- }
- }
- return result;
-}
-
-#define AM_MEM_ARENA_PUSH_ARRAY(arena, T, count) (am_mem_arena_push((arena), sizeof(T) * (count)))
-
-internal void am_mem_arena_pop_to(MemArena *a, u64 pos) {
- if (pos < a->pos) {
- a->pos = pos;
-
- u64 aligned = ALIGN_UP_POW_2(a->pos, AM_MEM_ARENA_COMMIT_BLOCK_SIZE);
- u64 next_commit_pos = CLAMP_TOP(aligned, a->cap);
- if (next_commit_pos < a->commit_pos) {
- u64 decommit_size = a->commit_pos - next_commit_pos;
- a->base->decommit(a->base->ctx, a->mem + a->commit_pos, decommit_size);
- a->commit_pos = next_commit_pos;
- }
- }
-}
-
-internal void am_mem_arena_release(MemArena *a) {
- a->base->release(a->base->ctx, a->mem, a->cap);
- *a = (MemArena){0};
-}
-
-// TODO: SIMD
-internal void am_mem_copy(void *dst, void *src, u64 size) {
- assert(dst);
- for (u64 i = 0; i < size; i++) {
- ((u8 *)dst)[i] = ((u8 *)src)[i];
- }
-}
-
-internal void am_mem_set(u64 size, void *dst, u8 byte) {
- assert(dst);
- for (u64 i = 0; i < size; i++) {
- ((u8 *)dst)[i] = byte;
- }
-}
-
-internal bool am_mem_equal(void *dst, void *src, u64 size) {
- for (u64 i = 0; i < size; i++) {
- if (((u8 *)dst)[i] != ((u8 *)src)[i]) {
- return false;
- }
- }
- return true;
-}
-
-internal void am_memory_test(void) {
- assert(MEM_KIB(10) == 10240);
- assert(MEM_MIB(10) == 10485760);
- assert(MEM_GIB(10) == 10737418240);
-
- {
- BaseAllocator *a = am_mem_base_allocator_malloc();
- u64 num_test_ints = 10;
- s32 *int_buf = a->reserve(NULL, num_test_ints * sizeof(s32));
- assert(int_buf);
- a->release(NULL, int_buf, 0);
- }
-
- {
- MemArena a = am_mem_arena_create(am_mem_base_allocator_malloc());
- am_mem_arena_push(&a, 1020);
- assert(a.pos == 1020);
- u64 p = a.pos;
- u64 cp = a.commit_pos;
-
- AM_MEM_ARENA_PUSH_ARRAY(&a, u8, a.cap - a.pos);
- assert(a.pos == a.cap);
- assert(a.commit_pos == a.cap);
-
- am_mem_arena_pop_to(&a, p);
- assert(a.pos == p);
- assert(a.commit_pos == cp);
-
- am_mem_arena_release(&a);
- assert(a.pos == 0);
- assert(a.commit_pos == 0);
- assert(a.mem == NULL);
- }
-
- {
- u8 src[10] = {0};
- u8 dst[10] = {0};
- for (u64 i = 0; i < ARRAY_COUNT(src); i++) {
- assert(i < UINT8_MAX);
- src[i] = (u8)i;
- }
-
- am_mem_copy(dst, src, ARRAY_COUNT(dst));
- assert(am_mem_equal(dst, src, ARRAY_COUNT(dst)));
- }
-}
-
-#endif // AM_MEMORY_H
diff --git a/2022/am_string.h b/2022/am_string.h
@@ -1,381 +0,0 @@
-#ifndef AM_STRING_H
-#define AM_STRING_H
-
-#ifndef AM_MEMORY_H
- #error "am_memory.h is required"
-#endif
-#ifndef AM_LIST_H
- #error "am_list.h is required"
-#endif
-
-typedef struct {
- usz size;
- u8 *str;
-} Str;
-
-typedef struct StrListNode StrListNode;
-struct StrListNode {
- StrListNode *next;
- Str s;
-};
-
-typedef struct {
- StrListNode *first;
- StrListNode *last;
- u64 node_count;
- u64 total_size;
-} StrList;
-
-#define AM_STR_LIT(s) (Str) { .str = (u8 *)(s), .size = sizeof(s) - 1, }
-#define AM_STR_EXPAND(s) (s32)((s).size), ((s).str)
-
-internal usz am_cstr_len(char *cstr) {
- usz len = 0;
- while (cstr && *cstr != '\0') {
- len++;
- cstr++;
- }
- return len;
-}
-
-internal Str am_str(u8 *str, usz size) {
- return (Str) { .size = size, .str = str, };
-}
-
-internal Str am_str_from_range(u8 *start, u8 *opl) {
- assert(start < opl);
- return am_str(start, (usz)(opl - start));
-}
-
-internal Str am_str_from_cstr(char *cstr, usz len) {
- return am_str((u8 *)cstr, len);
-}
-
-// TODO: Use string interning
-internal bool am_str_eq(Str s1, Str s2) {
- if (s1.size != s2.size) {
- return false;
- }
-
- for (usz i = 0; i < s1.size; i++) {
- if (s1.str[i] != s2.str[i]) {
- return false;
- }
- }
-
- return true;
-}
-
-internal bool am_cstr_eq(char *cstr1, char *cstr2) {
- usz len1 = am_cstr_len(cstr1);
- usz len2 = am_cstr_len(cstr2);
- return am_str_eq(am_str_from_cstr(cstr1, len1), am_str_from_cstr(cstr2, len2));
-}
-
-internal Str am_str_line(Str s, u8 *cursor) {
- u8 *opl = s.str + s.size;
-
- assert(cursor >= s.str && cursor < opl);
-
- u8 *end = cursor;
- while (end < opl) {
- if (*end == '\n') {
- break;
- }
- end++;
- }
-
- u8 *beginning = cursor - (*cursor == '\n');
- while (beginning > s.str) {
- if (*beginning == '\n') {
- beginning++;
- break;
- }
- beginning--;
- }
-
- return am_str_from_range(beginning, end);
-}
-
-internal bool am_str_contains(Str s, char c) {
- for (usz i = 0; i < s.size; i++) {
- if (s.str[i] == c) {
- return true;
- }
- }
- return false;
-}
-
-internal bool am_cstr_contains(char *s, usz len, char c) {
- return am_str_contains(am_str_from_cstr(s, len), c);
-}
-
-internal bool am_str_cstr_eq(Str s, char *cstr) {
- return am_str_eq(s, am_str_from_cstr(cstr, am_cstr_len(cstr)));
-}
-
-internal void am_str_list_append(MemArena *arena, StrList *list, Str s) {
- StrListNode *node = am_mem_arena_push(arena, sizeof(StrListNode));
- *node = (StrListNode) {
- .s = s,
- };
- SLL_QUEUE_PUSH(list->first, list->last, node);
- list->node_count += 1;
- list->total_size += s.size;
-}
-
-internal void am_str_list_discard_empty(StrList *list) {
- assert(list);
- if (list->node_count) {
- StrListNode *previous = NULL;
-
- for (StrListNode *n = list->first; n; n = n->next) {
- if (n->s.size == 0) {
- assert(list->node_count > 0);
- list->node_count--;
- if (previous) {
- previous->next = n->next;
- } else {
- list->first = n->next;
- }
- } else {
- previous = n;
- }
- }
- }
-}
-
-typedef struct {
- Str pre;
- Str mid;
- Str post;
-} StringJoinOptions;
-
-internal Str am_str_join(MemArena *arena, StrList *list, StringJoinOptions *options) {
- StringJoinOptions join;
- if (options) {
- join = *options;
- } else {
- join = (StringJoinOptions){0};
- }
-
- Str s = {0};
-
- if (list->node_count) {
- assert(list->node_count > 0);
-
- u64 total_size = list->total_size
- + join.pre.size
- + (join.mid.size * (list->node_count - 1))
- + join.post.size;
-
- s = (Str) {
- .str = AM_MEM_ARENA_PUSH_ARRAY(arena, u8, total_size),
- .size = total_size,
- };
-
- u8 *p = s.str;
- am_mem_copy(p, join.pre.str, join.pre.size);
- p += join.pre.size;
-
- bool is_mid = false;
- for (StrListNode *n = list->first; n; n = n->next) {
- if (is_mid) {
- am_mem_copy(p, join.mid.str, join.mid.size);
- p += join.mid.size;
- }
-
- am_mem_copy(p, n->s.str, n->s.size);
- p += n->s.size;
-
- is_mid = true;
- }
-
- am_mem_copy(p, join.post.str, join.post.size);
- p += join.post.size;
- }
-
- return s;
-}
-
-internal StrList am_str_split(MemArena *arena, Str s, u8 *split_chars, u64 split_char_count) {
- StrList list = {0};
-
- u8 *cursor = s.str;
- u8 *split_beginning = cursor;
- u8 *opl = s.str + s.size;
- while (cursor <= opl) {
- bool split_byte = false;
- for (u64 i = 0; i < split_char_count; i++) {
- if (split_chars[i] == *cursor) {
- split_byte = true;
- break;
- }
- }
-
- if (split_byte) {
- if (cursor == split_beginning) {
- am_str_list_append(arena, &list, AM_STR_LIT(""));
- } else {
- am_str_list_append(arena, &list, am_str_from_range(split_beginning, cursor));
- }
- split_beginning = cursor + 1;
- }
- cursor++;
- }
-
- return list;
-}
-
-internal void am_string_test(void) {
- assert(am_cstr_len("abcdefg") == 7);
- assert(am_cstr_len("") == 0);
- assert(am_cstr_len("\0") == 0);
- assert(am_cstr_eq("", ""));
- assert(am_cstr_eq("\0", "\0"));
- assert(am_cstr_eq("abc", "abc"));
- assert(!am_cstr_eq("ABC", "abc"));
- assert(!am_cstr_eq("", " "));
- assert(!am_cstr_eq("abc", "abcde"));
- assert(!am_str_cstr_eq(AM_STR_LIT("abcd"), "abc"));
- assert(am_str_cstr_eq(AM_STR_LIT("abc"), "abc"));
- assert(am_cstr_contains("abc", 3, 'c'));
- assert(am_cstr_contains("a c", 3, ' '));
- assert(am_cstr_contains("", 1, '\0'));
- assert(!am_cstr_contains("abc", 3, 'z'));
- assert(!am_cstr_contains("", 0, 'z'));
- assert(!am_cstr_contains("", 0, '\0'));
- assert(am_cstr_contains("https://www.example.com", 23, '/'));
-
- {
- StrList l = {0};
- MemArena a = am_mem_arena_create(am_mem_base_allocator_malloc());
- Str strings[] = {
- AM_STR_LIT("one"),
- AM_STR_LIT("two"),
- AM_STR_LIT("three"),
- };
-
- for (u64 i = 0; i < ARRAY_COUNT(strings); i++) {
- am_str_list_append(&a, &l, strings[i]);
- }
-
- Str joined = am_str_join(&a, &l, &(StringJoinOptions){
- .pre = AM_STR_LIT("Joined: '"),
- .mid = AM_STR_LIT(", "),
- .post = AM_STR_LIT("'."),
- });
-
- printf("%.*s\n", AM_STR_EXPAND(joined));
-
- StrList split = am_str_split(&a, AM_STR_LIT(", one, two, three, four, "), (u8 *)", ", 2);
-
- for (StrListNode *n = split.first; n; n = n->next) {
- printf("split: '%.*s'\n", AM_STR_EXPAND(n->s));
- }
-
- am_mem_arena_release(&a);
- }
-
- {
- MemArena a = am_mem_arena_create(am_mem_base_allocator_malloc());
- StrList lines = am_str_split(&a, AM_STR_LIT("one|two|three|four"), (u8 *)"|", 1);
-
- Str expected[] = {
- AM_STR_LIT("one"),
- AM_STR_LIT("two"),
- AM_STR_LIT("three"),
- AM_STR_LIT("four"),
- };
-
- size_t i = 0;
- for (StrListNode *line = lines.first; line; line = line->next) {
- printf("Expected: '%.*s', Got: '%.*s'\n", AM_STR_EXPAND(expected[i]), AM_STR_EXPAND(line->s));
- assert(i < ARRAY_COUNT(expected));
- assert(am_str_eq(line->s, expected[i]));
- i++;
- }
-
- assert(i + 1 == ARRAY_COUNT(expected));
- am_mem_arena_release(&a);
- }
-
- {
- MemArena a = am_mem_arena_create(am_mem_base_allocator_malloc());
- StrList lines = am_str_split(&a, AM_STR_LIT("|one|two||three|four|"), (u8 *)"|", 1);
-
- Str expected[] = {
- AM_STR_LIT(""),
- AM_STR_LIT("one"),
- AM_STR_LIT("two"),
- AM_STR_LIT(""),
- AM_STR_LIT("three"),
- AM_STR_LIT("four"),
- AM_STR_LIT(""),
- };
-
- size_t i = 0;
- for (StrListNode *line = lines.first; line; line = line->next) {
- printf("Expected: '%.*s', Got: '%.*s'\n", AM_STR_EXPAND(expected[i]), AM_STR_EXPAND(line->s));
- assert(i < ARRAY_COUNT(expected));
- assert(am_str_eq(line->s, expected[i]));
- i++;
- }
-
- assert(i + 1 == ARRAY_COUNT(expected));
- am_mem_arena_release(&a);
- }
-
- {
- MemArena a = am_mem_arena_create(am_mem_base_allocator_malloc());
- StrList lines = am_str_split(&a, AM_STR_LIT("|||"), (u8 *)"|", 1);
-
- Str expected[] = {
- AM_STR_LIT(""),
- AM_STR_LIT(""),
- AM_STR_LIT(""),
- AM_STR_LIT(""),
- };
-
- size_t i = 0;
- for (StrListNode *line = lines.first; line; line = line->next) {
- printf("Expected: '%.*s', Got: '%.*s'\n", AM_STR_EXPAND(expected[i]), AM_STR_EXPAND(line->s));
- assert(i < ARRAY_COUNT(expected));
- assert(am_str_eq(line->s, expected[i]));
- i++;
- }
-
- assert(i + 1 == ARRAY_COUNT(expected));
- am_mem_arena_release(&a);
- }
-
- {
- MemArena a = am_mem_arena_create(am_mem_base_allocator_malloc());
- StrList lines = am_str_split(&a, AM_STR_LIT(""), (u8 *)"|", 1);
-
- assert(lines.node_count == 0);
- am_mem_arena_release(&a);
- }
-
- {
- MemArena a = am_mem_arena_create(am_mem_base_allocator_malloc());
- StrList lines = am_str_split(&a, AM_STR_LIT("one two three four"), (u8 *)"|", 1);
-
- Str expected[] = {
- AM_STR_LIT("one two three four"),
- };
-
- size_t i = 0;
- for (StrListNode *line = lines.first; line; line = line->next) {
- printf("Expected: '%.*s', Got: '%.*s'\n", AM_STR_EXPAND(expected[i]), AM_STR_EXPAND(line->s));
- assert(i < ARRAY_COUNT(expected));
- assert(am_str_eq(line->s, expected[i]));
- i++;
- }
-
- assert(i + 1 == ARRAY_COUNT(expected));
- am_mem_arena_release(&a);
- }
-}
-
-#endif // AM_STRING_H
diff --git a/2022/day01.c b/2022/day01.c
@@ -5,7 +5,7 @@ input=$(basename "$0")
output="$outdir"/$(basename "$0" .c)
mkdir --parents "$outdir" || exit
echo "Building ${output}." || exit
-clang -std=c11 -O0 -g -Wall -Wextra -pedantic -Wno-unused-function "$input" -o "$output" || exit
+clang -std=c11 -O0 -g -Wall -Wextra -pedantic -Wno-unused-function -I../../amlibs/ "$input" -o "$output" || exit
if [ "$1" = "-r" ];
then
./"$output" "$@"
diff --git a/2022/day02.c b/2022/day02.c
@@ -5,7 +5,7 @@ input=$(basename "$0")
output="$outdir"/$(basename "$0" .c)
mkdir --parents "$outdir" || exit
echo "Building ${output}." || exit
-clang -std=c11 -O0 -g -Wall -Wextra -pedantic -Wno-unused-function "$input" -o "$output" || exit
+clang -std=c11 -O0 -g -Wall -Wextra -pedantic -Wno-unused-function -I../../amlibs/ "$input" -o "$output" || exit
if [ "$1" = "-r" ];
then
./"$output" "$@"