diff options
Diffstat (limited to 'include/ui_utils.h')
-rw-r--r-- | include/ui_utils.h | 151 |
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 |