summaryrefslogtreecommitdiff
path: root/include/ui_utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/ui_utils.h')
-rw-r--r--include/ui_utils.h151
1 files changed, 151 insertions, 0 deletions
diff --git a/include/ui_utils.h b/include/ui_utils.h
new file mode 100644
index 0000000..5510433
--- /dev/null
+++ b/include/ui_utils.h
@@ -0,0 +1,151 @@
+#ifndef UI_UTILS
+#define UI_UTILS
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#ifdef _GNU_SOURCE
+#include <stdalign.h>
+#endif
+
+#define UI_INTERNAL static
+#define UI_GLOBAL
+
+typedef signed char i8;
+typedef unsigned char u8;
+typedef signed short int i16;
+typedef unsigned short int u16;
+typedef signed int i32;
+typedef unsigned int u32;
+typedef signed long int i64;
+typedef unsigned long int u64;
+
+UI_INTERNAL void __crash_error(const char *message, const char *file,
+ u32 line) {
+ fprintf(stderr, "(%s:%d): %s\n", file, line, message);
+ exit(1);
+}
+
+#define crash_error(message) __crash_error(message, __FILE__, __LINE__)
+#define crash_errno() __crash_error(strerror(errno), __FILE__, __LINE__)
+
+#define assert_mmap(expr) \
+ if ((expr) == MAP_FAILED) \
+ crash_errno()
+
+#define assert_errno(expr) \
+ if (errno != 0) \
+ crash_errno()
+
+#define assert_success(actual, expected) \
+ if ((actual) != expected) \
+ crash_error("assertion failed")
+
+#define assert_failure(actual, expected) \
+ if ((actual) == expected) \
+ crash_error("assertion failed")
+
+typedef struct {
+ uint64_t size;
+ const char *buf;
+} String;
+
+String string_slice(const char *cStr) {
+ String str = {0};
+ str.size = strlen(cStr);
+ str.buf = cStr;
+
+ return str;
+}
+
+typedef struct {
+ u64 size;
+ u64 capacity;
+ u8 *buffer;
+} Arena;
+
+Arena *arena_init(void) {
+ Arena *arena = malloc(sizeof(Arena));
+ size_t page_size = sysconf(_SC_PAGE_SIZE);
+ arena->capacity = page_size * 4;
+
+ assert_mmap(arena->buffer = mmap(0, arena->capacity, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0));
+
+ return arena;
+}
+
+void *arena_alloc(Arena *arena, u64 size, u8 align) {
+ void *mem;
+ u8 offset;
+
+ u64 available = arena->capacity - arena->size;
+ if (size > available) {
+ assert_mmap(arena->buffer = mremap(arena->buffer, arena->size,
+ arena->size + (available * 2), 0));
+ }
+
+ mem = &(arena->buffer[arena->size]);
+ offset = (u64)mem % align;
+ mem = (void *)((u64)mem + offset);
+ arena->size += size + offset;
+ return mem;
+}
+
+void arena_zero(Arena *arena) {
+ arena->size = 0;
+ memset(arena->buffer, 0, arena->size);
+}
+
+void arena_free(Arena *arena) {
+ if (munmap(arena->buffer, arena->capacity) == -1) {
+ crash_error("can't unmap arena");
+ }
+
+ arena->buffer = 0;
+ arena->size = 0;
+ arena->capacity = 0;
+}
+
+typedef struct {
+ Arena *arena;
+ u64 initial;
+} ArenaTemp;
+
+ArenaTemp *arena_temp(Arena *arena) {
+ ArenaTemp *temp = malloc(sizeof(ArenaTemp));
+ temp->arena = arena;
+ temp->initial = arena->size;
+
+ return temp;
+}
+
+void arena_temp_free(ArenaTemp *temp) {
+ temp->arena->size = temp->initial;
+ free(temp);
+}
+
+#if __STDC_VERSION__ >= 202311L
+#define arena_type(arena, type) \
+ (type *)(arena_alloc(arena, sizeof(type), alignof(type)))
+#define arena_array(arena, type, size) \
+ (type *)(arena_alloc(arena, sizeof(type) * size, alignof(type)))
+#elif __STDC_VERSION__ >= 201112L
+(type *)(arena_alloc(arena, sizeof(type), _Alignof(type)))
+#define arena_array(arena, type, size) \
+ (type *)(arena_alloc(arena, sizeof(type) * size, _Alignof(type)))
+#else
+#define arena_type(arena, type) \
+ (type *)(arena_alloc(arena, sizeof(type), __alignof__(type)))
+#define arena_array(arena, type, size) \
+ (type *)(arena_alloc(arena, sizeof(type) * size, __alignof__(type)))
+#endif
+
+#endif