Reorganise files

This commit is contained in:
2024-06-16 12:29:43 +01:00
parent 8f5bee45c6
commit f6dd7e7aa8
14 changed files with 0 additions and 0 deletions

87
src/core/cpath/cpath.c Normal file
View File

@@ -0,0 +1,87 @@
#include "cpath.h"
#include "aliases.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#if defined(__unix__) || defined(__APPLE__) || defined(__ANDROID__)
internal char path_sep = '/';
#elif defined(_WIN32) || defined(_WIN64)
internal char path_sep = '\\';
#endif
void join_root_and_leaf(const char *root, const char *leaf, char *dst);
void join_path(char *dst, u64 count, ...) {
va_list args;
va_start(args, count);
for (u64 i = 0; i < count; ++i) {
join_root_and_leaf(dst, va_arg(args, const char *), dst);
}
va_end(args);
}
void dirup(char *dst, u64 levels, const char *path) {
if (levels < 1) {
return;
}
u64 end_index = 0;
u64 sep_count = 0;
u64 full_length;
u64 length;
length = full_length = strlen(path);
if (path[length - 1] == path_sep) {
--length;
}
for (i64 i = length - 1; i >= 0; --i) {
if (path[i] == path_sep) {
++sep_count;
end_index = i;
if (sep_count == levels) {
break;
}
}
}
if (sep_count < levels) {
end_index = 0;
}
if (dst == path) {
memset(&dst[end_index], 0, full_length - end_index);
} else {
u64 dst_length = strlen(dst);
memset(dst, 0, dst_length);
strncpy(dst, path, end_index);
}
}
void join_root_and_leaf(const char *root, const char *leaf, char *dst) {
u64 root_length = strlen(root);
u64 root_end = root_length - 1;
u64 leaf_length = strlen(leaf);
u64 leaf_start = 0;
if (root[root_end] == path_sep) {
--root_end;
}
if (leaf[leaf_start] == path_sep) {
++leaf_start;
}
memcpy(dst, root, ++root_end);
dst[root_end] = path_sep;
memcpy(&(dst[++root_end]), &(leaf[leaf_start]), leaf_length - leaf_start);
}

25
src/core/cpath/cpath.h Normal file
View File

@@ -0,0 +1,25 @@
#ifndef PATH_UTILS_H
#define PATH_UTILS_H
#include "aliases.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#define NUMPARTS(...) \
(sizeof((const char *[]){"", __VA_ARGS__}) / sizeof(const char *) - 1)
#define wapp_cpath_join_path(DST, ...) \
join_path(DST, NUMPARTS(__VA_ARGS__), __VA_ARGS__)
#define wapp_cpath_dirname(DST, PATH) dirup(DST, 1, PATH)
#define wapp_cpath_dirup(DST, COUNT, PATH) dirup(DST, COUNT, PATH)
void join_path(char *dst, u64 count, ...);
void dirup(char *dst, u64 levels, const char *path);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // !PATH_UTILS_H

View File

@@ -0,0 +1,119 @@
#include "mem_arena.h"
#include "aliases.h"
#include "mem_utils.h"
#include "misc_utils.h"
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#ifndef DEFAULT_ALIGNMENT
// Why 2 * sizeof(void *) instead of sizeof(void *)
// https://handmade.network/forums/t/6860-alignment_arena_allocator
#define DEFAULT_ALIGNMENT (2 * sizeof(void *))
#endif /* ifndef DEFAULT_ALIGNMENT */
#define ARENA_MINIMUM_CAPACITY 1024
struct arena {
u8 *buf;
u8 *offset;
u64 capacity;
bool committed;
#ifdef WAPP_PLATFORM_WINDOWS
wapp_misc_utils_padding_size(sizeof(u8 *) * 2 + sizeof(u64) + sizeof(bool));
#endif // ifdef WAPP_PLATFORM_WINDOWS
};
// PUBLIC API
bool wapp_mem_arena_init(Arena **arena, u64 base_capacity, MemAllocFlags flags,
bool zero_buffer) {
if (!arena || *arena || base_capacity == 0) {
return false;
}
*arena = (Arena *)calloc(1, sizeof(Arena));
Arena *arena_ptr = *arena;
if (!arena_ptr) {
return false;
}
u64 arena_capacity = base_capacity >= ARENA_MINIMUM_CAPACITY
? base_capacity
: ARENA_MINIMUM_CAPACITY;
arena_ptr->buf = (u8 *)wapp_mem_util_alloc(
NULL, arena_capacity, WAPP_MEM_ACCESS_READ_WRITE, flags,
zero_buffer ? WAPP_MEM_INIT_INITIALISED : WAPP_MEM_INIT_UNINITIALISED);
if (!(arena_ptr->buf)) {
wapp_mem_arena_destroy(arena);
return false;
}
arena_ptr->capacity = arena_capacity;
arena_ptr->offset = arena_ptr->buf;
arena_ptr->committed =
(flags & WAPP_MEM_ALLOC_COMMIT) == WAPP_MEM_ALLOC_COMMIT;
return true;
}
void *wapp_mem_arena_alloc(Arena *arena, u64 size) {
return wapp_mem_arena_alloc_aligned(arena, size, DEFAULT_ALIGNMENT);
}
void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment) {
if (!arena) {
return NULL;
}
u8 *alloc_start = arena->offset;
u8 *output = wapp_mem_util_align_forward((void *)alloc_start, alignment);
if (output + size >= arena->buf + arena->capacity) {
return NULL;
}
arena->offset = output + size;
#ifdef WAPP_PLATFORM_WINDOWS
if (!(arena->committed)) {
output = (u8 *)wapp_mem_util_alloc(
alloc_start, (uptr)(arena->offset) - (uptr)(alloc_start),
WAPP_MEM_ACCESS_READ_WRITE, WAPP_MEM_ALLOC_COMMIT,
WAPP_MEM_INIT_INITIALISED);
}
#else
memset(output, 0, size);
#endif // ifdef WAPP_PLATFORM_WINDOWS
return (void *)output;
}
void wapp_mem_arena_clear(Arena *arena) {
if (!arena) {
return;
}
memset(arena->buf, 0, arena->offset - arena->buf);
arena->offset = arena->buf;
}
void wapp_mem_arena_destroy(Arena **arena) {
if (!arena) {
return;
}
Arena *arena_ptr = *arena;
if (arena_ptr->buf) {
wapp_mem_util_free(arena_ptr->buf, arena_ptr->capacity);
}
arena_ptr->buf = arena_ptr->offset = NULL;
arena_ptr->capacity = 0;
free(*arena);
*arena = NULL;
}

View File

@@ -0,0 +1,37 @@
#ifndef MEM_ARENA_H
#define MEM_ARENA_H
#include "aliases.h"
#include "mem_utils.h"
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
typedef struct arena Arena;
#define wapp_mem_arena_init_default(arena_dptr, base_capacity) \
(wapp_mem_arena_init(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE, \
false))
#define wapp_mem_arena_init_commit(arena_dptr, base_capacity) \
(wapp_mem_arena_init(arena_dptr, base_capacity, \
WAPP_MEM_ALLOC_RESERVE | WAPP_MEM_ALLOC_COMMIT, false))
#define wapp_mem_arena_init_zero(arena_dptr, base_capacity) \
(wapp_mem_arena_init(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE, true))
#define wapp_mem_arena_init_commit_and_zero(arena_dptr, base_capacity) \
(wapp_mem_arena_init(arena_dptr, base_capacity, \
WAPP_MEM_ALLOC_RESERVE | WAPP_MEM_ALLOC_COMMIT, true))
bool wapp_mem_arena_init(Arena **arena, u64 base_capacity, MemAllocFlags flags,
bool zero_buffer);
void *wapp_mem_arena_alloc(Arena *arena, u64 size);
void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment);
void wapp_mem_arena_clear(Arena *arena);
void wapp_mem_arena_destroy(Arena **arena);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // !MEM_ARENA_H

View File

@@ -0,0 +1,115 @@
#include "mem_utils.h"
#include "aliases.h"
#include "platform.h"
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#if defined(WAPP_PLATFORM_WINDOWS)
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <memoryapi.h>
internal const i32 access_types[] = {
[WAPP_MEM_ACCESS_NONE] = PAGE_NOACCESS,
[WAPP_MEM_ACCESS_READ_ONLY] = PAGE_READONLY,
[WAPP_MEM_ACCESS_EXEC_ONLY] = PAGE_EXECUTE,
[WAPP_MEM_ACCESS_READ_WRITE] = PAGE_READWRITE,
[WAPP_MEM_ACCESS_READ_EXEC] = PAGE_EXECUTE_READ,
[WAPP_MEM_ACCESS_READ_WRITE_EXEC] = PAGE_EXECUTE_READWRITE,
};
internal inline void *alloc_windows(void *addr, u64 size, MemAccess access,
MemAllocFlags flags);
#elif defined(WAPP_PLATFORM_POSIX)
#include <sys/mman.h>
internal const i32 access_types[] = {
[WAPP_MEM_ACCESS_NONE] = PROT_NONE,
[WAPP_MEM_ACCESS_READ_ONLY] = PROT_READ,
[WAPP_MEM_ACCESS_EXEC_ONLY] = PROT_EXEC,
[WAPP_MEM_ACCESS_READ_WRITE] = PROT_READ | PROT_WRITE,
[WAPP_MEM_ACCESS_READ_EXEC] = PROT_READ | PROT_EXEC,
[WAPP_MEM_ACCESS_READ_WRITE_EXEC] = PROT_READ | PROT_WRITE | PROT_EXEC,
};
internal inline void *alloc_posix(void *addr, u64 size, MemAccess access,
MemAllocFlags flags);
#else
#error "Unrecognised platform"
#endif
internal bool is_power_of_two(u64 num) { return (num & (num - 1)) == 0; }
void *wapp_mem_util_align_forward(void *ptr, u64 alignment) {
if (!ptr) {
return NULL;
}
assert(is_power_of_two(alignment));
uptr p = (uptr)ptr;
uptr align = (uptr)alignment;
// Similar to p % align, but it's a faster implementation that works fine
// because align is guaranteed to be a power of 2
uptr modulo = p & (align - 1);
if (modulo != 0) {
p += align - modulo;
}
return (void *)p;
}
void *wapp_mem_util_alloc(void *addr, u64 size, MemAccess access,
MemAllocFlags flags, MemInitType type) {
#if defined(WAPP_PLATFORM_WINDOWS)
// Ensure memory is committed if it's meant to be initialised
if (type == WAPP_MEM_INIT_INITIALISED) {
flags |= WAPP_MEM_ALLOC_COMMIT;
}
void *output = alloc_windows(addr, size, access, flags);
#elif defined(WAPP_PLATFORM_POSIX)
void *output = alloc_posix(addr, size, access, flags);
#else
return NULL;
#endif
if (type == WAPP_MEM_INIT_INITIALISED) {
memset(output, 0, size);
}
return output;
}
void wapp_mem_util_free(void *ptr, u64 size) {
#if defined(WAPP_PLATFORM_WINDOWS)
VirtualFree(ptr, size, MEM_RELEASE);
#elif defined(WAPP_PLATFORM_POSIX)
munmap(ptr, size);
#endif
}
#ifdef WAPP_PLATFORM_WINDOWS
internal inline void *alloc_windows(void *addr, u64 size, MemAccess access,
MemAllocFlags flags) {
return VirtualAlloc(addr, (SIZE_T)size, flags, access_types[access]);
}
#endif
#if defined(WAPP_PLATFORM_POSIX)
internal inline void *alloc_posix(void *addr, u64 size, MemAccess access,
MemAllocFlags flags) {
i32 alloc_flags = flags | MAP_ANON | MAP_PRIVATE;
#if defined(WAPP_PLATFORM_LINUX) || defined(WAPP_PLATFORM_GNU) || \
defined(WAPP_PLATFORM_NET_BSD)
alloc_flags |= MAP_NORESERVE;
#endif
return mmap(addr, size, access_types[access], alloc_flags, -1, 0);
}
#endif

View File

@@ -0,0 +1,61 @@
#ifndef MEM_UTILS_H
#define MEM_UTILS_H
#include "aliases.h"
#include "platform.h"
#if defined(WAPP_PLATFORM_WINDOWS)
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <memoryapi.h>
#elif defined(WAPP_PLATFORM_POSIX)
#include <sys/mman.h>
#else
#error "Unrecognised platform"
#endif
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
typedef enum mem_access {
WAPP_MEM_ACCESS_NONE,
WAPP_MEM_ACCESS_READ_ONLY,
WAPP_MEM_ACCESS_EXEC_ONLY,
WAPP_MEM_ACCESS_READ_WRITE,
WAPP_MEM_ACCESS_READ_EXEC,
WAPP_MEM_ACCESS_READ_WRITE_EXEC,
} MemAccess;
typedef enum mem_alloc_flags {
#if defined(WAPP_PLATFORM_WINDOWS)
WAPP_MEM_ALLOC_RESERVE = MEM_RESERVE,
WAPP_MEM_ALLOC_COMMIT = MEM_COMMIT,
#elif defined(WAPP_PLATFORM_LINUX) || defined(WAPP_PLATFORM_GNU)
WAPP_MEM_ALLOC_RESERVE = 0,
WAPP_MEM_ALLOC_COMMIT = MAP_POPULATE,
#elif defined(WAPP_PLATFORM_FREE_BSD)
WAPP_MEM_ALLOC_RESERVE = 0,
WAPP_MEM_ALLOC_COMMIT = MAP_PREFAULT_READ,
#elif defined(WAPP_PLATFORM_BSD) || defined(WAPP_PLATFORM_UNIX) || \
defined(WAPP_PLATFORM_APPLE)
WAPP_MEM_ALLOC_RESERVE = 0,
WAPP_MEM_ALLOC_COMMIT = 0,
#endif
} MemAllocFlags;
typedef enum mem_init_type {
WAPP_MEM_INIT_UNINITIALISED,
WAPP_MEM_INIT_INITIALISED,
} MemInitType;
void *wapp_mem_util_align_forward(void *ptr, u64 alignment);
void *wapp_mem_util_alloc(void *addr, u64 size, MemAccess access,
MemAllocFlags flags, MemInitType type);
void wapp_mem_util_free(void *ptr, u64 size);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // !MEM_UTILS_H

View File

@@ -0,0 +1,34 @@
#ifndef BASIC_STRING_H
#define BASIC_STRING_H
#include "aliases.h"
#include <stdio.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
typedef struct bstr BasicString;
struct bstr {
u64 size;
const char *buf;
};
typedef struct strvw StringView;
struct strvw {
const u64 size;
const char *buf;
};
#define new_string(STR) \
{ .size = strlen(STR), .buf = STR }
#define wapp_bstr_new(STR) ((BasicString)new_string(STR))
#define wapp_strvw_new(STR) ((StringView)new_string(STR))
#define wapp_string_print(STR) (printf("%.*s\n", (i32)STR.size, STR.buf))
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // !BASIC_STRING_H

View File

@@ -0,0 +1,191 @@
#include "dstr.h"
#include "aliases.h"
#include "mem_arena.h"
#include "platform.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Use this scalar to allocate extra memory in order to avoid having to
// constantly reallocate
#define CAPACITY_SCALAR 8
#define MINIMUM_DSTR_CAPACITY 1024
struct dstr {
u64 capacity;
u64 size;
#ifdef WAPP_PLATFORM_WINDOWS
char *buf;
#else
char buf[];
#endif // WAPP_PLATFORM_WINDOWS
};
String *wapp_dstr_with_capacity(u64 capacity, Arena *arena) {
if (!arena) {
return NULL;
}
String *out =
(String *)wapp_mem_arena_alloc(arena, sizeof(String) + capacity + 1);
if (!out) {
return NULL;
}
out->capacity = capacity;
out->size = 0;
return out;
}
String *wapp_dstr_from_string(const char *str, Arena *arena) {
if (!str || !arena) {
return NULL;
}
u64 length = strlen(str);
u64 capacity = length * CAPACITY_SCALAR;
capacity =
capacity >= MINIMUM_DSTR_CAPACITY ? capacity : MINIMUM_DSTR_CAPACITY;
String *out = wapp_dstr_with_capacity(capacity, arena);
if (!out) {
return NULL;
}
out->size = length;
strncpy(out->buf, str, length + 1);
return out;
}
StringUpdate wapp_dstr_update(String **dst, const char *src, Arena *arena) {
if (!dst || !(*dst)) {
return (StringUpdate){.updated = false, .str = *dst};
}
u64 length = strlen(src);
String *str = *dst;
if (length >= str->capacity) {
if (!arena) {
return (StringUpdate){.updated = false, .str = *dst};
}
String *new_str = wapp_dstr_from_string(src, arena);
if (!new_str) {
return (StringUpdate){.updated = false, .str = *dst};
}
return (StringUpdate){.updated = true, .str = new_str};
}
memset(str->buf, 0, str->capacity);
str->size = length;
strncpy(str->buf, src, length + 1);
return (StringUpdate){.updated = true, .str = *dst};
}
StringUpdate wapp_dstr_concat(String **dst, const char *src, Arena *arena) {
if (!dst || !(*dst)) {
return (StringUpdate){.updated = false, .str = *dst};
}
u64 src_length = strlen(src);
if (src_length == 0) {
return (StringUpdate){.updated = false, .str = *dst};
}
u64 new_length = (*dst)->size + src_length;
#ifdef WAPP_PLATFORM_WINDOWS
char *str =
wapp_mem_util_alloc(NULL, new_length + 1, WAPP_MEM_ACCESS_READ_WRITE,
WAPP_MEM_ALLOC_RESERVE | WAPP_MEM_ALLOC_COMMIT,
WAPP_MEM_INIT_INITIALISED);
if (!str) {
return (StringUpdate){.updated = false, .str = *dst};
}
#else
char str[new_length + 1];
memset(str, 0, new_length + 1);
#endif /* ifdef WAPP_PLATFORM_WINDOWS */
strncpy(str, (*dst)->buf, (*dst)->size);
strncat(str, src, new_length + 1 - (*dst)->size);
return wapp_dstr_update(dst, str, arena);
}
void wapp_dstr_clear(String *str) {
if (!str || str->size == 0) {
return;
}
memset(str->buf, 0, str->capacity);
str->size = 0;
}
void wapp_dstr_print(const String *str) {
if (!str) {
return;
}
printf("%.*s\n", (i32)str->size, str->buf);
}
i64 wapp_dstr_find(const String *str, const char *substr) {
if (!str || !substr) {
return -1;
}
u64 substr_length = strlen(substr);
if (substr_length == 0 || substr_length > str->size) {
return -1;
}
const char *s1;
for (u64 i = 0; i < str->size; ++i) {
if (i + substr_length > str->size) {
break;
}
s1 = &(str->buf[i]);
if (strncmp(s1, substr, substr_length) == 0) {
return i;
}
}
return -1;
}
u64 wapp_dstr_length(const String *str) {
if (!str) {
return 0;
}
return str->size;
}
u64 wapp_dstr_capacity(const String *str) {
if (!str) {
return 0;
}
return str->capacity;
}
const char *wapp_dstr_to_cstr(const String *str) {
if (!str) {
return "";
}
return str->buf;
}

View File

@@ -0,0 +1,41 @@
#ifndef DSTR_H
#define DSTR_H
#include "aliases.h"
#include "mem_arena.h"
#include "misc_utils.h"
#include "platform.h"
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
typedef struct dstr String;
typedef struct string_update StringUpdate;
struct string_update {
String *str;
bool updated;
#ifdef WAPP_PLATFORM_WINDOWS
wapp_misc_utils_padding_size(sizeof(bool) + sizeof(String *));
#endif // WAPP_PLATFORM_WINDOWS
};
String *wapp_dstr_with_capacity(u64 capacity, Arena *arena);
String *wapp_dstr_from_string(const char *str, Arena *arena);
StringUpdate wapp_dstr_update(String **dst, const char *src, Arena *arena);
StringUpdate wapp_dstr_concat(String **dst, const char *src, Arena *arena);
void wapp_dstr_clear(String *str);
void wapp_dstr_print(const String *str);
i64 wapp_dstr_find(const String *str, const char *substr);
u64 wapp_dstr_length(const String *str);
u64 wapp_dstr_capacity(const String *str);
const char *wapp_dstr_to_cstr(const String *str);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // !DSTR_H