Recreate base64 project

This commit is contained in:
Abdelrahman Said 2025-08-10 23:30:27 +01:00
commit e90d14344e
63 changed files with 11139 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
b64

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# C testing projects
Recreating the projects from [intro-to-zig](https://git.thewizardapprentice.com/abdelrahman/intro-to-zig) in C

140
base64/base64.c Normal file
View File

@ -0,0 +1,140 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "base64.h"
#include "../wapp/wapp.h"
#include <math.h>
internal Str8RO alphabet = wapp_str8_lit_ro("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
internal c8 char_at(u8 index);
internal u8 char_index(c8 c);
internal u64 calc_encode_length(Str8RO *input);
internal u64 calc_decode_length(Str8RO *input);
Str8 *encode(Allocator *allocator, Str8RO *input) {
if (input->size == 0) {
return NULL;
}
u64 n_out = calc_encode_length(input);
Str8 *out = wapp_str8_alloc_and_fill_buf(allocator, n_out);
if (!out) return NULL;
u8 buf[3] = {0};
u8 count = 0;
u64 iout = 0;
for (u64 i = 0; i < input->size; ++i) {
buf[count] = wapp_str8_get(input, i);
count += 1;
if (count == 3) {
wapp_str8_set(out, iout, char_at(buf[0] >> 2));
wapp_str8_set(out, iout + 1, char_at(((buf[0] & 0x03) << 4) + (buf[1] >> 4)));
wapp_str8_set(out, iout + 2, char_at(((buf[1] & 0x0f) << 2) + (buf[2] >> 6)));
wapp_str8_set(out, iout + 3, char_at(buf[2] & 0x3f));
iout += 4;
count = 0;
}
}
if (count == 1) {
wapp_str8_set(out, iout, char_at(buf[0] >> 2));
wapp_str8_set(out, iout + 1, char_at((buf[0] & 0x03) << 4));
wapp_str8_set(out, iout + 2, '=');
wapp_str8_set(out, iout + 3, '=');
}
if (count == 2) {
wapp_str8_set(out, iout, char_at(buf[0] >> 2));
wapp_str8_set(out, iout + 1, char_at(((buf[0] & 0x03) << 4) + (buf[1] >> 4)));
wapp_str8_set(out, iout + 2, char_at((buf[1] & 0x0f) << 2));
wapp_str8_set(out, iout + 3, '=');
iout += 4;
}
return out;
}
Str8 *decode(Allocator *allocator, Str8RO *input) {
if (input->size == 0) {
return NULL;
}
u64 n_out = calc_decode_length(input);
Str8 *out = wapp_str8_alloc_and_fill_buf(allocator, n_out);
if (!out) return NULL;
u8 buf[4] = {0};
u8 count = 0;
u64 iout = 0;
for (u64 i = 0; i < input->size; ++i) {
buf[count] = char_index(wapp_str8_get(input, i));
count += 1;
if (count == 4) {
wapp_str8_set(out, iout, (buf[0] << 2) + (buf[1] >> 4));
if (buf[2] != 64) {
wapp_str8_set(out, iout + 1, (buf[1] << 4) + (buf[2] >> 2));
}
if (buf[3] != 64) {
wapp_str8_set(out, iout + 2, (buf[2] << 6) + buf[3]);
}
iout += 3;
count = 0;
}
}
return out;
}
internal c8 char_at(u8 index) {
return wapp_str8_get(&alphabet, index);
}
internal u8 char_index(c8 c) {
if (c == '=') {
return 64;
}
u8 index = 0;
for (u8 i = 0; i < 63; ++i) {
if (char_at(i) == c) {
break;
}
index += 1;
}
return index;
}
internal u64 calc_encode_length(Str8RO *input) {
if (input->size < 3) {
return 4;
}
u64 n_groups = (u64)(ceilf((f32)input->size / 3.0f));
return n_groups * 4;
}
internal u64 calc_decode_length(Str8RO *input) {
if (input->size < 4) {
return 3;
}
u64 n_groups = (u64)(floorf((f32)input->size / 4.0f));
u64 groups = n_groups * 3;
for (u64 i = input->size; i > 0; --i) {
if (wapp_str8_get(input, i) == '=') {
groups -= 1;
}
}
return groups;
}

11
base64/base64.h Normal file
View File

@ -0,0 +1,11 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef BASE64_H
#define BASE64_H
#include "../wapp/wapp.h"
Str8 *encode(Allocator *allocator, Str8RO *input);
Str8 *decode(Allocator *allocator, Str8RO *input);
#endif // !BASE64_H

5
base64/build Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
script_dir="$(dirname $0)"
clang $script_dir/*.c $script_dir/../wapp/wapp.c -lm -o b64

23
base64/main.c Normal file
View File

@ -0,0 +1,23 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "base64.h"
#include "../wapp/wapp.h"
#include <stdio.h>
int main(void) {
Allocator allocator = wapp_mem_arena_allocator_init(MB(10));
Str8RO text = wapp_str8_lit_ro("Testing some more stuff");
Str8RO etext = wapp_str8_lit_ro("VGVzdGluZyBzb21lIG1vcmUgc3R1ZmY=");
Str8 *encoded_text = encode(&allocator, &text);
Str8 *decoded_text = decode(&allocator, &etext);
wapp_runtime_assert(encoded_text != NULL && decoded_text != NULL, "Failed to allocate strings");
printf("Encoded text: " WAPP_STR8_SPEC "\n", wapp_str8_varg(*encoded_text));
printf("Decoded text: " WAPP_STR8_SPEC "\n", wapp_str8_varg(*decoded_text));
wapp_mem_arena_allocator_destroy(&allocator);
return 0;
}

View File

@ -0,0 +1,67 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef ALIASES_H
#define ALIASES_H
#include "../platform/platform.h"
#include <stdint.h>
#if WAPP_PLATFORM_C_VERSION >= WAPP_PLATFORM_C11_VERSION && !defined(WAPP_PLATFORM_APPLE)
#include <uchar.h>
#if WAPP_PLATFORM_C_VERSION >= WAPP_PLATFORM_C23_VERSION
#define c8 char8_t
#else
#define c8 uint8_t
#endif // !WAPP_PLATFORM_C23_VERSION
#define c16 char16_t
#define c32 char32_t
#else
#define c8 uint8_t
#define c16 uint16_t
#define c32 uint32_t
#endif // !WAPP_PLATFORM_C11_VERSION
#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
#define u64 uint64_t
#define b32 uint32_t
#ifndef WAPP_PLATFORM_CPP
#ifndef false
#define false (b32)0
#endif // !false
#ifndef true
#define true (b32)1
#endif // !true
#endif // !WAPP_PLATFORM_CPP
#define i8 int8_t
#define i16 int16_t
#define i32 int32_t
#define i64 int64_t
#define f32 float
#define f64 double
#define f128 long double
#define uptr uintptr_t
#define iptr intptr_t
#define external extern
#define internal static
#define persistent static
#ifdef WAPP_PLATFORM_CPP
#define class_mem static
#define BEGIN_C_LINKAGE extern "C" {
#define END_C_LINKAGE }
#endif // WAPP_PLATFORM_CPP
#endif // !ALIASES_H

View File

@ -0,0 +1,41 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_ASSERT_H
#define WAPP_ASSERT_H
#include "../aliases/aliases.h"
#include "../platform/platform.h"
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#define wapp_static_assert(EXPR, MSG) extern char ASSERTION_FAILED[EXPR ? 1 : -1]
#define wapp_runtime_assert(EXPR, MSG) __wapp_runtime_assert(EXPR, MSG)
#ifdef WAPP_DEBUG_ASSERT
#define wapp_debug_assert(EXPR, MSG) wapp_runtime_assert(EXPR, MSG)
#else
#define wapp_debug_assert(EXPR, MSG)
#endif
#define __wapp_runtime_assert(EXPR, MSG) do { \
if (!(EXPR)) { \
fprintf( \
stderr, \
"%s:%d (In function `%s`): Assertion failed (%" PRIu32 ")\nDiagnostic: %s\n\n", \
__FILE__, __LINE__, __func__, \
EXPR, MSG \
); \
abort(); \
} \
} while(false)
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !WAPP_ASSERT_H

View File

@ -0,0 +1,56 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef MISC_UTILS_H
#define MISC_UTILS_H
#include "../aliases/aliases.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#define KB(SIZE) (SIZE * 1024ull)
#define MB(SIZE) (KB(SIZE) * 1024)
#define GB(SIZE) (MB(SIZE) * 1024)
#define TB(SIZE) (GB(SIZE) * 1024)
#define wapp_misc_utils_padding_size(SIZE) u8 reserved_padding[sizeof(void *) - ((SIZE) % sizeof(void *))]
#define U64_RSHIFT_OR_1(X) (((u64)X) | (((u64)X) >> 1))
#define U64_RSHIFT_OR_2(X) (((u64)X) | (((u64)X) >> 2))
#define U64_RSHIFT_OR_4(X) (((u64)X) | (((u64)X) >> 4))
#define U64_RSHIFT_OR_8(X) (((u64)X) | (((u64)X) >> 8))
#define U64_RSHIFT_OR_16(X) (((u64)X) | (((u64)X) >> 16))
#define U64_RSHIFT_OR_32(X) (((u64)X) | (((u64)X) >> 32))
#define wapp_misc_utils_u64_round_up_pow2(X) ( \
( \
U64_RSHIFT_OR_32( \
U64_RSHIFT_OR_16( \
U64_RSHIFT_OR_8( \
U64_RSHIFT_OR_4( \
U64_RSHIFT_OR_2( \
U64_RSHIFT_OR_1(X - 1) \
) \
) \
) \
) \
) \
) + 1 \
)
#ifdef WAPP_PLATFORM_CPP
#define wapp_misc_utils_va_args_count(T, ...) va_args_count<T>(__VA_ARGS__)
#else
#define wapp_misc_utils_va_args_count(T, ...) (sizeof((T[]){__VA_ARGS__})/sizeof(T))
#endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
template <typename T, typename... Args>
constexpr u64 va_args_count(Args&&...) {
return sizeof...(Args);
}
#endif // !WAPP_PLATFORM_CPP
#endif // !MISC_UTILS_H

View File

@ -0,0 +1,114 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef PLATFORM_H
#define PLATFORM_H
#if defined(__ANDROID__)
#define WAPP_PLATFORM_ANDROID
#define WAPP_PLATFORM_POSIX
#elif defined(__FreeBSD__)
#define WAPP_PLATFORM_FREE_BSD
#define WAPP_PLATFORM_BSD
#define WAPP_PLATFORM_POSIX
#elif defined(__NetBSD__)
#define WAPP_PLATFORM_NET_BSD
#define WAPP_PLATFORM_BSD
#define WAPP_PLATFORM_POSIX
#elif defined(__OpenBSD__)
#define WAPP_PLATFORM_OPEN_BSD
#define WAPP_PLATFORM_BSD
#define WAPP_PLATFORM_POSIX
#elif defined(__DragonFly__)
#define WAPP_PLATFORM_DRAGON_FLY
#define WAPP_PLATFORM_BSD
#define WAPP_PLATFORM_POSIX
#elif defined(__bsdi__)
#define WAPP_PLATFORM_BSD
#define WAPP_PLATFORM_POSIX
#elif defined(__linux__) || defined(linux) || defined(__linux) || defined(__gnu_linux__)
#define WAPP_PLATFORM_LINUX
#define WAPP_PLATFORM_POSIX
#elif defined(__GNU__) || defined(__gnu_hurd__)
#define WAPP_PLATFORM_GNU
#define WAPP_PLATFORM_POSIX
#elif defined(__APPLE__) || defined(__MACH__)
#include <TargetConditionals.h>
#if TARGET_OS_IPHONE
#define WAPP_PLATFORM_IOS
#define WAPP_PLATFORM_APPLE
#define WAPP_PLATFORM_POSIX
#elif TARGET_OS_MAC
#define WAPP_PLATFORM_MACOS
#define WAPP_PLATFORM_APPLE
#define WAPP_PLATFORM_POSIX
#else
#error "Unrecognised Apple platform"
#endif
#elif defined(_WIN64)
#define WAPP_PLATFORM_WINDOWS64
#define WAPP_PLATFORM_WINDOWS
#elif defined(_WIN32)
#define WAPP_PLATFORM_WINDOWS32
#define WAPP_PLATFORM_WINDOWS
#elif defined(__CYGWIN__)
#define WAPP_PLATFORM_CYGWIN
#define WAPP_PLATFORM_WINDOWS
#elif defined(__unix__) || defined(__unix)
#define WAPP_PLATFORM_UNIX
#define WAPP_PLATFORM_POSIX
#else
#error "Unrecognised platform"
#endif
#ifdef __cplusplus
#define WAPP_PLATFORM_CPP
#define WAPP_PLATFORM_CPP_VERSION __cplusplus
#define WAPP_PLATFORM_CPP98_VERSION 199711L
#define WAPP_PLATFORM_CPP11_VERSION 201103L
#define WAPP_PLATFORM_CPP14_VERSION 201402L
#define WAPP_PLATFORM_CPP17_VERSION 201703L
#define WAPP_PLATFORM_CPP20_VERSION 202002L
#define WAPP_PLATFORM_CPP23_VERSION 202302L
#if WAPP_PLATFORM_CPP_VERSION == WAPP_PLATFORM_CPP98_VERSION
#define WAPP_PLATFORM_CPP98
#elif WAPP_PLATFORM_CPP_VERSION == WAPP_PLATFORM_CPP11_VERSION
#define WAPP_PLATFORM_CPP11
#elif WAPP_PLATFORM_CPP_VERSION == WAPP_PLATFORM_CPP14_VERSION
#define WAPP_PLATFORM_CPP14
#elif WAPP_PLATFORM_CPP_VERSION == WAPP_PLATFORM_CPP17_VERSION
#define WAPP_PLATFORM_CPP17
#elif WAPP_PLATFORM_CPP_VERSION == WAPP_PLATFORM_CPP20_VERSION
#define WAPP_PLATFORM_CPP20
#elif WAPP_PLATFORM_CPP_VERSION == WAPP_PLATFORM_CPP23_VERSION
#define WAPP_PLATFORM_CPP23
#else
#error "Unrecognised C++ version"
#endif
#else
#define WAPP_PLATFORM_C
#if defined(__STDC_VERSION__)
#define WAPP_PLATFORM_C_VERSION __STDC_VERSION__
#define WAPP_PLATFORM_C99_VERSION 199901L
#define WAPP_PLATFORM_C11_VERSION 201112L
#define WAPP_PLATFORM_C17_VERSION 201710L
#define WAPP_PLATFORM_C23_VERSION 202311L
#if WAPP_PLATFORM_C_VERSION == WAPP_PLATFORM_C99_VERSION
#define WAPP_PLATFORM_C99
#elif WAPP_PLATFORM_C_VERSION == WAPP_PLATFORM_C11_VERSION
#define WAPP_PLATFORM_C11
#elif WAPP_PLATFORM_C_VERSION == WAPP_PLATFORM_C17_VERSION
#define WAPP_PLATFORM_C17
#elif WAPP_PLATFORM_C_VERSION == WAPP_PLATFORM_C23_VERSION
#define WAPP_PLATFORM_C23
#else
#error "Unrecognised C version"
#endif
#else
#define WAPP_PLATFORM_C89
#endif
#endif // !__cplusplus
#endif // !PLATFORM_H

11
wapp/common/wapp_common.h Normal file
View File

@ -0,0 +1,11 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_COMMON_H
#define WAPP_COMMON_H
#include "aliases/aliases.h"
#include "assert/assert.h"
#include "misc/misc_utils.h"
#include "platform/platform.h"
#endif // !WAPP_COMMON_H

View File

@ -0,0 +1,147 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "mem_arena.h"
#include "../utils/mem_utils.h"
#include "../../../common/aliases/aliases.h"
#include "../../../common/assert/assert.h"
#include "../../../common/misc/misc_utils.h"
#include "../../os/mem/mem_os.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 KB(16) // Allocate minimum of 4 pages
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
};
bool wapp_mem_arena_init_custom(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 = wapp_misc_utils_u64_round_up_pow2(
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) {
wapp_debug_assert(arena != NULL, "`arena` should not be 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)) {
wapp_mem_util_alloc(alloc_start, (uptr)(arena->offset) - (uptr)(alloc_start),
WAPP_MEM_ACCESS_READ_WRITE, WAPP_MEM_ALLOC_COMMIT,
WAPP_MEM_INIT_UNINITIALISED);
}
#endif // ifdef WAPP_PLATFORM_WINDOWS
memset(output, 0, size);
return (void *)output;
}
void *wapp_mem_arena_realloc(Arena *arena, void *ptr, u64 old_size, u64 new_size) {
if ((u8*)ptr < arena->buf || (u8*)ptr > arena->offset ||
arena->offset + new_size >= arena->buf + arena->capacity) {
return NULL;
}
void *new_ptr = wapp_mem_arena_alloc(arena, new_size);
if (!new_ptr) {
return NULL;
}
u64 copy_size = new_size <= old_size ? new_size : old_size;
memcpy(new_ptr, ptr, copy_size);
return new_ptr;
}
void *wapp_mem_arena_realloc_aligned(Arena *arena, void *ptr, u64 old_size, u64 new_size, u64 alignment) {
if ((u8*)ptr < arena->buf || (u8*)ptr > arena->offset ||
arena->offset + new_size >= arena->buf + arena->capacity) {
return NULL;
}
void *new_ptr = wapp_mem_arena_alloc_aligned(arena, new_size, alignment);
if (!new_ptr) {
return NULL;
}
u64 copy_size = new_size <= old_size ? new_size : old_size;
memcpy(new_ptr, ptr, copy_size);
return new_ptr;
}
void wapp_mem_arena_clear(Arena *arena) {
wapp_debug_assert(arena != NULL, "`arena` should not be NULL");
memset(arena->buf, 0, arena->offset - arena->buf);
arena->offset = arena->buf;
}
void wapp_mem_arena_destroy(Arena **arena) {
wapp_debug_assert(arena != NULL && (*arena) != NULL, "`arena` double pointer is not valid");
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,43 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef MEM_ARENA_H
#define MEM_ARENA_H
#include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h"
#include "../../os/mem/mem_os.h"
#include <stdbool.h>
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
typedef struct arena Arena;
#define wapp_mem_arena_init(arena_dptr, base_capacity) \
(wapp_mem_arena_init_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE, false))
#define wapp_mem_arena_init_commit(arena_dptr, base_capacity) \
(wapp_mem_arena_init_custom(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_custom(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_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE | WAPP_MEM_ALLOC_COMMIT, true))
/**
* Arena initialisation function. `wapp_mem_arena_init_custom` provides the most
* control over how the Arena is initialised. Wrapper macros are provided for
* easier use.
*/
bool wapp_mem_arena_init_custom(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_realloc(Arena *arena, void *ptr, u64 old_size, u64 new_size);
void *wapp_mem_arena_realloc_aligned(Arena *arena, void *ptr, u64 old_size, u64 new_size, u64 alignment);
void wapp_mem_arena_clear(Arena *arena);
void wapp_mem_arena_destroy(Arena **arena);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !MEM_ARENA_H

View File

@ -0,0 +1,59 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "mem_arena_allocator.h"
#include "mem_arena.h"
#include "../../../common/aliases/aliases.h"
#include "../../os/mem/mem_os.h"
internal inline void *mem_arena_alloc(u64 size, void *alloc_obj);
internal inline void *mem_arena_alloc_aligned(u64 size, u64 alignment, void *alloc_obj);
internal inline void *mem_arena_realloc(void *ptr, u64 old_size, u64 new_size, void *alloc_obj);
internal inline void *mem_arena_realloc_aligned(void *ptr, u64 old_size, u64 new_size, u64 alignment,
void *alloc_obj);
Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags flags, bool zero_buffer) {
Allocator allocator = {0};
bool initialised = wapp_mem_arena_init_custom((Arena **)(&allocator.obj), base_capacity, flags, zero_buffer);
if (!initialised) {
return allocator;
}
allocator.alloc = mem_arena_alloc;
allocator.alloc_aligned = mem_arena_alloc_aligned;
allocator.realloc = mem_arena_realloc;
allocator.realloc_aligned = mem_arena_realloc_aligned;
return allocator;
}
void wapp_mem_arena_allocator_clear(Allocator *allocator) {
wapp_mem_arena_clear((Arena *)(allocator->obj));
}
void wapp_mem_arena_allocator_destroy(Allocator *allocator) {
wapp_mem_arena_destroy((Arena **)(&(allocator->obj)));
*allocator = (Allocator){0};
}
internal inline void *mem_arena_alloc(u64 size, void *alloc_obj) {
Arena *arena = (Arena *)alloc_obj;
return wapp_mem_arena_alloc(arena, size);
}
internal inline void *mem_arena_alloc_aligned(u64 size, u64 alignment, void *alloc_obj) {
Arena *arena = (Arena *)alloc_obj;
return wapp_mem_arena_alloc_aligned(arena, size, alignment);
}
internal inline void *mem_arena_realloc(void *ptr, u64 old_size, u64 new_size, void *alloc_obj) {
Arena *arena = (Arena *)alloc_obj;
return wapp_mem_arena_realloc(arena, ptr, old_size, new_size);
}
internal inline void *mem_arena_realloc_aligned(void *ptr, u64 old_size, u64 new_size, u64 alignment,
void *alloc_obj) {
Arena *arena = (Arena *)alloc_obj;
return wapp_mem_arena_realloc_aligned(arena, ptr, old_size, new_size, alignment);
}

View File

@ -0,0 +1,44 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef MEM_ARENA_ALLOCATOR_H
#define MEM_ARENA_ALLOCATOR_H
#include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h"
#include "../../../primitives/mem_allocator/mem_allocator.h"
#include "../../os/mem/mem_os.h"
#include <stdbool.h>
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#define wapp_mem_arena_allocator_init(base_capacity) \
(wapp_mem_arena_allocator_init_custom(base_capacity, WAPP_MEM_ALLOC_RESERVE, false))
#define wapp_mem_arena_allocator_init_commit(base_capacity) \
(wapp_mem_arena_allocator_init_custom(base_capacity, WAPP_MEM_ALLOC_RESERVE | WAPP_MEM_ALLOC_COMMIT, false))
#define wapp_mem_arena_allocator_init_zero(base_capacity) \
(wapp_mem_arena_allocator_init_custom(base_capacity, WAPP_MEM_ALLOC_RESERVE, true))
#define wapp_mem_arena_allocator_init_commit_and_zero(base_capacity) \
(wapp_mem_arena_allocator_init_custom(base_capacity, WAPP_MEM_ALLOC_RESERVE | WAPP_MEM_ALLOC_COMMIT, true))
/**
* Wraps an Arena in an Allocator object. It attempts to initialise the Arena
* and, if successful, defines the operations supported by it to be used by the
* Allocator.
*
* An Arena allocator only supports normal allocation and aligned allocation.
* Reallocation, aligned reallocation and freeing aren't implemented.
*
* The `wapp_mem_arena_allocator_init_custom` provides the most control over how
* the Arena is initialised. Wrapper macros are provided for easier use.
*/
Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags flags, bool zero_buffer);
void wapp_mem_arena_allocator_clear(Allocator *allocator);
void wapp_mem_arena_allocator_destroy(Allocator *allocator);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !MEM_ARENA_ALLOCATOR_H

View File

@ -0,0 +1,27 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "mem_utils.h"
#include "../../../common/aliases/aliases.h"
#include "../../../common/assert/assert.h"
#include <stdbool.h>
#include <stddef.h>
internal bool is_power_of_two(u64 num) { return (num & (num - 1)) == 0; }
void *wapp_mem_util_align_forward(void *ptr, u64 alignment) {
wapp_debug_assert(ptr != NULL, "`ptr` should not be NULL");
wapp_runtime_assert(is_power_of_two(alignment), "`alignment` value is not a power of two");
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;
}

View File

@ -0,0 +1,19 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef MEM_UTILS_H
#define MEM_UTILS_H
#include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
void *wapp_mem_util_align_forward(void *ptr, u64 alignment);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !MEM_UTILS_H

136
wapp/core/os/cpath/cpath.c Normal file
View File

@ -0,0 +1,136 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "cpath.h"
#include "../../../common/aliases/aliases.h"
#include "../../../common/misc/misc_utils.h"
#include "../../mem/arena/mem_arena_allocator.h"
#include "../../../primitives/dbl_list/dbl_list.h"
#include "../../../primitives/mem_allocator/mem_allocator.h"
#include "../../../primitives/strings/str8/str8.h"
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts) {
if (!dst || !parts) {
return CPATH_JOIN_INVALID_ARGS;
}
if (parts->node_count == 0) {
return CPATH_JOIN_EMPTY_PARTS;
}
Str8 separator = wapp_str8_buf(4);
wapp_str8_push_back(&separator, PATH_SEP);
u64 required_capacity = parts->node_count * separator.size + wapp_str8_list_total_size(parts);
if (dst->capacity < required_capacity) {
return CPATH_JOIN_INSUFFICIENT_DST_CAPACITY;
}
// Handle first node
const Str8Node *first_node = wapp_str8_list_get(parts, 0);
wapp_str8_copy_str8_capped(dst, first_node->item);
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
const Str8Node *node = first_node;
u64 node_index = 1;
bool running = node_index < parts->node_count;
while (running && node->next) {
node = node->next;
if (node->item->size == 0) {
continue;
}
if (dst->size > 0) {
char dst_last = wapp_str8_get(dst, dst->size - 1);
char node_start = wapp_str8_get(node->item, 0);
bool add_path_sep = dst_last != PATH_SEP && node_start != PATH_SEP;
if (add_path_sep) {
wapp_str8_concat_capped(dst, &separator);
}
}
wapp_str8_concat_capped(dst, node->item);
++node_index;
running = node_index < parts->node_count;
}
return CPATH_JOIN_SUCCESS;
}
Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels) {
Str8 *output = NULL;
if (!allocator || !path) {
goto RETURN_DIRUP;
}
bool absolute = wapp_str8_get(path, 0) == PATH_SEP;
Str8 separator = wapp_str8_buf(4);
wapp_str8_push_back(&separator, PATH_SEP);
if (path->size == 0) {
output = wapp_str8_alloc_buf(allocator, 16);
if (!output) {
goto RETURN_DIRUP;
}
wapp_str8_push_back(output, absolute ? PATH_SEP : '.');
goto RETURN_DIRUP;
}
if (levels < 1) {
output = wapp_str8_alloc_str8(allocator, path);
goto RETURN_DIRUP;
}
Allocator tmp_arena = wapp_mem_arena_allocator_init(MB(8));
if (wapp_mem_allocator_invalid(&tmp_arena)) {
goto RETURN_DIRUP;
}
Str8List *parts = wapp_str8_split(&tmp_arena, path, &separator);
if (!parts) {
goto RETURN_DIRUP;
}
if (levels >= parts->node_count) {
output = wapp_str8_alloc_buf(allocator, 16);
if (!output) {
goto LIST_CLEANUP_DIRUP;
}
wapp_str8_push_back(output, absolute ? PATH_SEP : '.');
} else {
for (u64 i = 0; i < levels; ++i) {
wapp_str8_list_pop_back(parts);
}
u64 alignment = sizeof(void *) * 2;
u64 alloc_size = wapp_str8_list_total_size(parts) + parts->node_count * separator.size;
u64 modulo = alloc_size & (alignment - 1);
alloc_size += alignment - modulo;
output = wapp_str8_alloc_buf(allocator, alloc_size);
if (output) {
if (absolute) {
wapp_str8_push_back(output, PATH_SEP);
}
Str8 *joined = wapp_str8_join(&tmp_arena, parts, &separator);
if (joined) {
wapp_str8_concat_capped(output, joined);
}
}
}
LIST_CLEANUP_DIRUP:
wapp_mem_arena_allocator_destroy(&tmp_arena);
RETURN_DIRUP:
return output;
}

View File

@ -0,0 +1,40 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef CPATH_H
#define CPATH_H
#include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h"
#include "../../../primitives/mem_allocator/mem_allocator.h"
#include "../../../primitives/strings/str8/str8.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_POSIX
#define PATH_SEP '/'
#elif defined(WAPP_PLATFORM_WINDOWS)
#define PATH_SEP '\\'
#else
#error "Unrecognised platform"
#endif
#define wapp_cpath_dirname(ALLOCATOR, PATH) dirup(ALLOCATOR, PATH, 1)
#define wapp_cpath_dirup(ALLOCATOR, PATH, COUNT) dirup(ALLOCATOR, PATH, COUNT)
enum {
CPATH_JOIN_SUCCESS = 0,
CPATH_JOIN_INVALID_ARGS,
CPATH_JOIN_EMPTY_PARTS,
CPATH_JOIN_INSUFFICIENT_DST_CAPACITY,
};
u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts);
Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !CPATH_H

31
wapp/core/os/mem/mem_os.c Normal file
View File

@ -0,0 +1,31 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "mem_os.h"
#include "mem_os_ops.h"
#include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h"
#include <assert.h>
#include <stdbool.h>
#include <string.h>
#if defined(WAPP_PLATFORM_WINDOWS)
#include "win/mem_os_win.h"
#elif defined(WAPP_PLATFORM_POSIX)
#include "posix/mem_os_posix.h"
#else
#error "Unrecognised platform"
#endif
void *wapp_mem_util_alloc(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) {
void *output = mem_util_allocate(addr, size, access, flags, type);
if (type == WAPP_MEM_INIT_INITIALISED) {
memset(output, 0, size);
}
return output;
}
void wapp_mem_util_free(void *ptr, u64 size) {
mem_util_free(ptr, size);
}

33
wapp/core/os/mem/mem_os.h Normal file
View File

@ -0,0 +1,33 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef MEM_OS_H
#define MEM_OS_H
#include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h"
#include "mem_os_ops.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#if defined(WAPP_PLATFORM_WINDOWS)
#include "win/mem_os_win.h"
#elif defined(WAPP_PLATFORM_POSIX)
#include "posix/mem_os_posix.h"
#else
#error "Unrecognised platform"
#endif
void *wapp_mem_util_alloc(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type);
void wapp_mem_util_free(void *ptr, u64 size);
external void *mem_util_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type);
external void mem_util_free(void *ptr, u64 size);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !MEM_OS_H

View File

@ -0,0 +1,30 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef MEM_OS_OPS_H
#define MEM_OS_OPS_H
#include "../../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
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_init_type {
WAPP_MEM_INIT_UNINITIALISED,
WAPP_MEM_INIT_INITIALISED,
} MemInitType;
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !MEM_OS_OPS_H

View File

@ -0,0 +1,36 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "../../../../common/aliases/aliases.h"
#include "../../../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_POSIX
#include "mem_os_posix.h"
#include "../mem_os_ops.h"
#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,
};
void *mem_util_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) {
(void)type;
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);
}
void mem_util_free(void *ptr, u64 size) {
munmap(ptr, size);
}
#endif // !WAPP_PLATFORM_POSIX

View File

@ -0,0 +1,35 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef MEM_OS_POSIX_H
#define MEM_OS_POSIX_H
#include "../../../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_POSIX
#include <sys/mman.h>
typedef enum mem_alloc_flags {
#if 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;
#endif // !WAPP_PLATFORM_POSIX
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !MEM_OS_POSIX_H

View File

@ -0,0 +1,37 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "../../../../common/aliases/aliases.h"
#include "../../../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_WINDOWS
#include "mem_os_win.h"
#include "../mem_os_ops.h"
#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,
};
void *mem_util_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) {
// Ensure memory is committed if it's meant to be initialised
if (type == WAPP_MEM_INIT_INITIALISED) {
flags |= WAPP_MEM_ALLOC_COMMIT;
}
return VirtualAlloc(addr, (SIZE_T)size, flags, access_types[access]);
}
void mem_util_free(void *ptr, u64 size) {
VirtualFree(ptr, size, MEM_RELEASE);
}
#endif // !WAPP_PLATFORM_WINDOWS

View File

@ -0,0 +1,29 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef MEM_OS_WIN_H
#define MEM_OS_WIN_H
#include "../../../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_WINDOWS
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <memoryapi.h>
typedef enum mem_alloc_flags {
WAPP_MEM_ALLOC_RESERVE = MEM_RESERVE,
WAPP_MEM_ALLOC_COMMIT = MEM_COMMIT,
} MemAllocFlags;
#endif // !WAPP_PLATFORM_WINDOWS
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !MEM_OS_WIN_H

View File

@ -0,0 +1,102 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "commander.h"
#include "commander_output.h"
#include "../utils/shell_utils.h"
#include "../../../mem/arena/mem_arena_allocator.h"
#include "../../../../common/aliases/aliases.h"
#include "../../../../common/misc/misc_utils.h"
#include "../../../../primitives/dbl_list/dbl_list.h"
#include "../../../../primitives/mem_allocator/mem_allocator.h"
#include "../../../../primitives/strings/str8/str8.h"
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CMD_BUF_LEN 8192
#define OUT_BUF_LEN 4096
internal inline CMDResult execute_command(Str8RO *cmd, CMDOutHandling out_handling, Str8 *out_buf);
internal inline CMDError get_command_output(FILE *fp, CMDOutHandling out_handling, Str8 *out_buf);
CMDResult wapp_shell_commander_execute(CMDOutHandling out_handling, Str8 *out_buf, const Str8List *cmd) {
if (!cmd) {
return CMD_NO_EXIT(SHELL_ERR_INVALID_ARGS);
}
Allocator arena = wapp_mem_arena_allocator_init(KB(500));
Str8 *cmd_str = wapp_str8_join(&arena, cmd, &wapp_str8_lit_ro(" "));
if (!cmd_str) {
wapp_mem_arena_allocator_destroy(&arena);
return CMD_NO_EXIT(SHELL_ERR_ALLOCATION_FAIL);
}
// Redirect output
cmd_str = wapp_str8_alloc_concat(&arena, cmd_str, &wapp_str8_lit_ro(" 2>&1"));
CMDResult output = execute_command(cmd_str, out_handling, out_buf);
wapp_mem_arena_allocator_destroy(&arena);
return output;
}
internal inline CMDResult execute_command(Str8RO *cmd, CMDOutHandling out_handling, Str8 *out_buf) {
char cmd_buf[CMD_BUF_LEN] = {0};
wapp_str8_copy_to_cstr(cmd_buf, cmd, CMD_BUF_LEN);
FILE *fp = wapp_shell_utils_popen(cmd_buf, "r");
if (!fp) {
return CMD_NO_EXIT(SHELL_ERR_PROC_START_FAIL);
}
CMDResult output;
CMDError err = get_command_output(fp, out_handling, out_buf);
if (err > SHELL_ERR_NO_ERROR) {
output = CMD_NO_EXIT(err);
goto EXECUTE_COMMAND_CLOSE;
}
i32 st = EXIT_SUCCESS;
err = get_output_status(fp, &st);
if (err > SHELL_ERR_NO_ERROR) {
output = CMD_NO_EXIT(err);
goto EXECUTE_COMMAND_CLOSE;
}
// Process is already closed in get_output_status
fp = NULL;
output = (CMDResult){
.exited = true,
.exit_code = st,
.error = SHELL_ERR_NO_ERROR,
};
EXECUTE_COMMAND_CLOSE:
if (fp) {
wapp_shell_utils_pclose(fp);
}
return output;
}
internal inline CMDError get_command_output(FILE *fp, CMDOutHandling out_handling, Str8 *out_buf) {
Str8 out = wapp_str8_buf(OUT_BUF_LEN);
out.size = fread((void *)out.buf, sizeof(u8), out.capacity, fp);
if (out_handling == SHELL_OUTPUT_CAPTURE && out_buf != NULL) {
if (out.size >= out_buf->capacity) {
return SHELL_ERR_OUT_BUF_FULL;
}
wapp_str8_concat_capped(out_buf, &out);
} else if (out_handling == SHELL_OUTPUT_PRINT) {
printf(WAPP_STR8_SPEC, wapp_str8_varg(out));
}
return SHELL_ERR_NO_ERROR;
}

View File

@ -0,0 +1,28 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef COMMANDER_H
#define COMMANDER_H
#include "commander_output.h"
#include "../../../../common/aliases/aliases.h"
#include "../../../../common/platform/platform.h"
#include "../../../../primitives/strings/str8/str8.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#define CMD_NO_EXIT(ERR) ((CMDResult){.exited = false, .exit_code = EXIT_FAILURE, .error = ERR})
CMDResult wapp_shell_commander_execute(CMDOutHandling out_handling, Str8 *out_buf, const Str8List *cmd);
external CMDError get_output_status(FILE *fp, i32 *status_out);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !COMMANDER_H

View File

@ -0,0 +1,45 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef COMMANDER_OUTPUT_H
#define COMMANDER_OUTPUT_H
#include "../../../../common/aliases/aliases.h"
#include "../../../../common/platform/platform.h"
#include <stdbool.h>
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
typedef enum {
SHELL_OUTPUT_DISCARD,
SHELL_OUTPUT_PRINT,
SHELL_OUTPUT_CAPTURE,
} CMDOutHandling;
typedef enum {
SHELL_ERR_NO_ERROR,
SHELL_ERR_INVALID_ARGS,
SHELL_ERR_ALLOCATION_FAIL,
SHELL_ERR_PROC_START_FAIL,
SHELL_ERR_OUT_BUF_FULL,
SHELL_ERR_PROC_EXIT_FAIL,
} CMDError;
typedef struct commander_result CMDResult;
struct commander_result {
i32 exit_code;
CMDError error;
bool exited;
#ifdef WAPP_PLATFORM_WINDOWS
#include "../../../../common/misc/misc_utils.h"
wapp_misc_utils_padding_size(sizeof(bool) + sizeof(i32) + sizeof(CMDError));
#endif // !WAPP_PLATFORM_WINDOWS
};
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !COMMANDER_OUTPUT_H

View File

@ -0,0 +1,25 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "../../../../../common/aliases/aliases.h"
#include "../../../../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_POSIX
#include "../commander_output.h"
#include "../../utils/shell_utils.h"
#include <stdio.h>
#include <stdlib.h>
CMDError get_output_status(FILE *fp, i32 *status_out) {
*status_out = wapp_shell_utils_pclose(fp);
if (!WIFEXITED(*status_out)) {
return SHELL_ERR_PROC_EXIT_FAIL;
}
*status_out = WEXITSTATUS(*status_out);
return SHELL_ERR_NO_ERROR;
}
#endif // !WAPP_PLATFORM_POSIX

View File

@ -0,0 +1,24 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "../../../../../common/aliases/aliases.h"
#include "../../../../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_WINDOWS
#include "../commander_output.h"
#include "../../utils/shell_utils.h"
#include <stdio.h>
CMDError get_output_status(FILE *fp, i32 *status_out) {
if (!feof(fp)) {
// Ensure process is closed on failure
wapp_shell_utils_pclose(fp);
return SHELL_ERR_PROC_EXIT_FAIL;
}
*status_out = wapp_shell_utils_pclose(fp);
return SHELL_ERR_NO_ERROR;
}
#endif // !WAPP_PLATFORM_WINDOWS

View File

@ -0,0 +1,36 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "../../../../../common/aliases/aliases.h"
#include "../../../../../common/platform/platform.h"
#include "../../../../../primitives/strings/str8/str8.h"
#ifdef WAPP_PLATFORM_POSIX
#include "../terminal_colours.h"
#include <stdio.h>
internal Str8RO colours[COUNT_TERM_COLOUR] = {
[WAPP_TERM_COLOUR_FG_BLACK] = wapp_str8_lit_ro_initialiser_list("\033[30m"),
[WAPP_TERM_COLOUR_FG_RED] = wapp_str8_lit_ro_initialiser_list("\033[31m"),
[WAPP_TERM_COLOUR_FG_GREEN] = wapp_str8_lit_ro_initialiser_list("\033[32m"),
[WAPP_TERM_COLOUR_FG_BLUE] = wapp_str8_lit_ro_initialiser_list("\033[34m"),
[WAPP_TERM_COLOUR_FG_CYAN] = wapp_str8_lit_ro_initialiser_list("\033[36m"),
[WAPP_TERM_COLOUR_FG_MAGENTA] = wapp_str8_lit_ro_initialiser_list("\033[35m"),
[WAPP_TERM_COLOUR_FG_YELLOW] = wapp_str8_lit_ro_initialiser_list("\033[33m"),
[WAPP_TERM_COLOUR_FG_WHITE] = wapp_str8_lit_ro_initialiser_list("\033[37m"),
[WAPP_TERM_COLOUR_FG_BR_BLACK] = wapp_str8_lit_ro_initialiser_list("\033[90m"),
[WAPP_TERM_COLOUR_FG_BR_RED] = wapp_str8_lit_ro_initialiser_list("\033[91m"),
[WAPP_TERM_COLOUR_FG_BR_GREEN] = wapp_str8_lit_ro_initialiser_list("\033[92m"),
[WAPP_TERM_COLOUR_FG_BR_BLUE] = wapp_str8_lit_ro_initialiser_list("\033[94m"),
[WAPP_TERM_COLOUR_FG_BR_CYAN] = wapp_str8_lit_ro_initialiser_list("\033[96m"),
[WAPP_TERM_COLOUR_FG_BR_MAGENTA] = wapp_str8_lit_ro_initialiser_list("\033[95m"),
[WAPP_TERM_COLOUR_FG_BR_YELLOW] = wapp_str8_lit_ro_initialiser_list("\033[93m"),
[WAPP_TERM_COLOUR_FG_BR_WHITE] = wapp_str8_lit_ro_initialiser_list("\033[97m"),
[WAPP_TERM_COLOUR_CLEAR] = wapp_str8_lit_ro_initialiser_list("\033[0m"),
};
void print_coloured_text(Str8RO *text, TerminalColour colour) {
printf(WAPP_STR8_SPEC WAPP_STR8_SPEC, wapp_str8_varg(colours[colour]), wapp_str8_varg((*text)));
}
#endif // !WAPP_PLATFORM_POSIX

View File

@ -0,0 +1,18 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "termcolour.h"
#include "terminal_colours.h"
#include "../../../../primitives/strings/str8/str8.h"
void wapp_shell_termcolour_print_text(Str8RO *text, TerminalColour colour) {
if (colour < WAPP_TERM_COLOUR_FG_BLACK || colour > WAPP_TERM_COLOUR_FG_BR_WHITE) {
return;
}
print_coloured_text(text, colour);
}
void wapp_shell_termcolour_clear_colour(void) {
Str8RO empty = wapp_str8_lit_ro("");
print_coloured_text(&empty, WAPP_TERM_COLOUR_CLEAR);
}

View File

@ -0,0 +1,24 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef TERM_COLOUR_H
#define TERM_COLOUR_H
#include "terminal_colours.h"
#include "../../../../common/aliases/aliases.h"
#include "../../../../common/platform/platform.h"
#include "../../../../primitives/strings/str8/str8.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
void wapp_shell_termcolour_print_text(Str8RO *text, TerminalColour colour);
void wapp_shell_termcolour_clear_colour(void);
external void print_coloured_text(Str8RO *text, TerminalColour colour);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !TERM_COLOUR_H

View File

@ -0,0 +1,39 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef TERMINAL_COLOURS_H
#define TERMINAL_COLOURS_H
#include "../../../../common/aliases/aliases.h"
#include "../../../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
typedef enum {
WAPP_TERM_COLOUR_FG_BLACK,
WAPP_TERM_COLOUR_FG_RED,
WAPP_TERM_COLOUR_FG_GREEN,
WAPP_TERM_COLOUR_FG_BLUE,
WAPP_TERM_COLOUR_FG_CYAN,
WAPP_TERM_COLOUR_FG_MAGENTA,
WAPP_TERM_COLOUR_FG_YELLOW,
WAPP_TERM_COLOUR_FG_WHITE,
WAPP_TERM_COLOUR_FG_BR_BLACK,
WAPP_TERM_COLOUR_FG_BR_RED,
WAPP_TERM_COLOUR_FG_BR_GREEN,
WAPP_TERM_COLOUR_FG_BR_BLUE,
WAPP_TERM_COLOUR_FG_BR_CYAN,
WAPP_TERM_COLOUR_FG_BR_MAGENTA,
WAPP_TERM_COLOUR_FG_BR_YELLOW,
WAPP_TERM_COLOUR_FG_BR_WHITE,
WAPP_TERM_COLOUR_CLEAR,
COUNT_TERM_COLOUR,
} TerminalColour;
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !TERMINAL_COLOURS_H

View File

@ -0,0 +1,73 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "../../../../../common/aliases/aliases.h"
#include "../../../../../common/platform/platform.h"
#include "../../../../../primitives/strings/str8/str8.h"
#ifdef WAPP_PLATFORM_WINDOWS
#include "../terminal_colours.h"
#include "../../../../../common/misc/misc_utils.h"
#include <stdio.h>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
typedef struct termcolour_data TermcolourData;
struct termcolour_data {
HANDLE handle;
WORD default_colour;
WORD current_colour;
wapp_misc_utils_padding_size(sizeof(HANDLE) + sizeof(WORD) + sizeof(WORD));
};
internal void init_data(TermcolourData *data);
internal WORD colours[COUNT_TERM_COLOUR] = {
[WAPP_TERM_COLOUR_FG_BLACK] = 0,
[WAPP_TERM_COLOUR_FG_RED] = FOREGROUND_RED,
[WAPP_TERM_COLOUR_FG_GREEN] = FOREGROUND_GREEN,
[WAPP_TERM_COLOUR_FG_BLUE] = FOREGROUND_BLUE,
[WAPP_TERM_COLOUR_FG_CYAN] = FOREGROUND_GREEN | FOREGROUND_BLUE,
[WAPP_TERM_COLOUR_FG_MAGENTA] = FOREGROUND_RED | FOREGROUND_BLUE,
[WAPP_TERM_COLOUR_FG_YELLOW] = FOREGROUND_RED | FOREGROUND_GREEN,
[WAPP_TERM_COLOUR_FG_WHITE] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
[WAPP_TERM_COLOUR_FG_BR_BLACK] = FOREGROUND_INTENSITY,
[WAPP_TERM_COLOUR_FG_BR_RED] = FOREGROUND_RED | FOREGROUND_INTENSITY,
[WAPP_TERM_COLOUR_FG_BR_GREEN] = FOREGROUND_GREEN | FOREGROUND_INTENSITY,
[WAPP_TERM_COLOUR_FG_BR_BLUE] = FOREGROUND_BLUE | FOREGROUND_INTENSITY,
[WAPP_TERM_COLOUR_FG_BR_CYAN] = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
[WAPP_TERM_COLOUR_FG_BR_MAGENTA] = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
[WAPP_TERM_COLOUR_FG_BR_YELLOW] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
[WAPP_TERM_COLOUR_FG_BR_WHITE] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
};
void print_coloured_text(Str8RO *text, TerminalColour colour) {
persistent TermcolourData data = {0};
if (data.handle == 0) {
init_data(&data);
}
if (colour == WAPP_TERM_COLOUR_CLEAR) {
data.current_colour = data.default_colour;
} else {
data.current_colour = colours[colour];
}
SetConsoleTextAttribute(data.handle, data.current_colour);
printf(WAPP_STR8_SPEC, wapp_str8_varg((*text)));
}
internal void init_data(TermcolourData *data) {
// create handle
data->handle = GetStdHandle(STD_OUTPUT_HANDLE);
// get console colour information
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(data->handle, &csbi);
data->default_colour = csbi.wAttributes;
data->current_colour = data->default_colour;
}
#endif // !WAPP_PLATFORM_WINDOWS

View File

@ -0,0 +1,26 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef SHELL_UTILS_H
#define SHELL_UTILS_H
#include "../../../../common/aliases/aliases.h"
#include "../../../../common/platform/platform.h"
#include <stdio.h>
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_WINDOWS
#define wapp_shell_utils_popen _popen
#define wapp_shell_utils_pclose _pclose
#else
#define wapp_shell_utils_popen popen
#define wapp_shell_utils_pclose pclose
#endif /* ifdef WAPP_PLATFORM_WINDOWS */
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !SHELL_UTILS_H

22
wapp/core/wapp_core.c Normal file
View File

@ -0,0 +1,22 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_CORE_C
#define WAPP_CORE_C
#include "wapp_core.h"
#include "os/shell/termcolour/posix/termcolour_posix.c"
#include "os/shell/termcolour/win/termcolour_win.c"
#include "os/shell/termcolour/termcolour.c"
#include "os/shell/commander/posix/commander_posix.c"
#include "os/shell/commander/win/commander_win.c"
#include "os/shell/commander/commander.c"
#include "os/cpath/cpath.c"
#include "os/mem/posix/mem_os_posix.c"
#include "os/mem/win/mem_os_win.c"
#include "os/mem/mem_os.c"
#include "mem/utils/mem_utils.c"
#include "mem/arena/mem_arena.c"
#include "mem/arena/mem_arena_allocator.c"
#include "../primitives/wapp_primitives.c"
#endif // !WAPP_CORE_C

22
wapp/core/wapp_core.h Normal file
View File

@ -0,0 +1,22 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_CORE_H
#define WAPP_CORE_H
#include "os/shell/termcolour/termcolour.h"
#include "os/shell/termcolour/terminal_colours.h"
#include "os/shell/commander/commander.h"
#include "os/shell/commander/commander_output.h"
#include "os/shell/utils/shell_utils.h"
#include "os/cpath/cpath.h"
#include "os/mem/posix/mem_os_posix.h"
#include "os/mem/win/mem_os_win.h"
#include "os/mem/mem_os_ops.h"
#include "os/mem/mem_os.h"
#include "mem/utils/mem_utils.h"
#include "mem/arena/mem_arena_allocator.h"
#include "mem/arena/mem_arena.h"
#include "../common/wapp_common.h"
#include "../primitives/wapp_primitives.h"
#endif // !WAPP_CORE_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,971 @@
/**
* THIS FILE IS AUTOMATICALLY GENERATED. ANY MODIFICATIONS TO IT WILL BE OVERWRITTEN
*/
#ifndef ARRAY_H
#define ARRAY_H
#include "../../common/aliases/aliases.h"
#include "../mem_allocator/mem_allocator.h"
#include "../../common/misc/misc_utils.h"
#include "../../common/aliases/aliases.h"
#include "../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#define wapp_str8_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((Str8Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(Str8)))
#define wapp_void_ptr_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((VoidPArray *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(void *)))
#define wapp_b32_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((B32Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(b32)))
#define wapp_char_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((CharArray *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(char)))
#define wapp_c8_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((C8Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(c8)))
#define wapp_c16_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((C16Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(c16)))
#define wapp_c32_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((C32Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(c32)))
#define wapp_i8_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((I8Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(i8)))
#define wapp_i16_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((I16Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(i16)))
#define wapp_i32_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((I32Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(i32)))
#define wapp_i64_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((I64Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(i64)))
#define wapp_u8_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((U8Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(u8)))
#define wapp_u16_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((U16Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(u16)))
#define wapp_u32_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((U32Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(u32)))
#define wapp_u64_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((U64Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(u64)))
#define wapp_f32_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((F32Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(f32)))
#define wapp_f64_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((F64Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(f64)))
#define wapp_f128_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((F128Array *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(f128)))
#define wapp_iptr_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((IptrArray *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(iptr)))
#define wapp_uptr_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY) ((UptrArray *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(uptr)))
#ifdef WAPP_PLATFORM_CPP
#define wapp_str8_array(...) ([&]() { \
persistent Str8 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(Str8, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return Str8Array{ \
buf, \
wapp_misc_utils_va_args_count(Str8, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(Str8, __VA_ARGS__) * 2), \
sizeof(Str8) \
}; \
}())
#define wapp_str8_array_with_capacity(CAPACITY) ([&]() { \
persistent Str8 buf[CAPACITY] = {}; \
return Str8Array{buf, 0, CAPACITY, sizeof(Str8)}; \
}())
#define wapp_str8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_str8_array_pop(ARRAY_PTR) : \
Str8{} \
)
#define wapp_void_ptr_array(...) ([&]() { \
persistent void * buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(void *, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return VoidPArray{ \
buf, \
wapp_misc_utils_va_args_count(void *, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(void *, __VA_ARGS__) * 2), \
sizeof(void *) \
}; \
}())
#define wapp_void_ptr_array_with_capacity(CAPACITY) ([&]() { \
persistent void * buf[CAPACITY] = {}; \
return VoidPArray{buf, 0, CAPACITY, sizeof(void *)}; \
}())
#define wapp_void_ptr_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_void_ptr_array_pop(ARRAY_PTR) : \
void *{} \
)
#define wapp_b32_array(...) ([&]() { \
persistent b32 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(b32, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return B32Array{ \
buf, \
wapp_misc_utils_va_args_count(b32, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(b32, __VA_ARGS__) * 2), \
sizeof(b32) \
}; \
}())
#define wapp_b32_array_with_capacity(CAPACITY) ([&]() { \
persistent b32 buf[CAPACITY] = {}; \
return B32Array{buf, 0, CAPACITY, sizeof(b32)}; \
}())
#define wapp_b32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_b32_array_pop(ARRAY_PTR) : \
b32{} \
)
#define wapp_char_array(...) ([&]() { \
persistent char buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(char, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return CharArray{ \
buf, \
wapp_misc_utils_va_args_count(char, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(char, __VA_ARGS__) * 2), \
sizeof(char) \
}; \
}())
#define wapp_char_array_with_capacity(CAPACITY) ([&]() { \
persistent char buf[CAPACITY] = {}; \
return CharArray{buf, 0, CAPACITY, sizeof(char)}; \
}())
#define wapp_char_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_char_array_pop(ARRAY_PTR) : \
char{} \
)
#define wapp_c8_array(...) ([&]() { \
persistent c8 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c8, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return C8Array{ \
buf, \
wapp_misc_utils_va_args_count(c8, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c8, __VA_ARGS__) * 2), \
sizeof(c8) \
}; \
}())
#define wapp_c8_array_with_capacity(CAPACITY) ([&]() { \
persistent c8 buf[CAPACITY] = {}; \
return C8Array{buf, 0, CAPACITY, sizeof(c8)}; \
}())
#define wapp_c8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_c8_array_pop(ARRAY_PTR) : \
c8{} \
)
#define wapp_c16_array(...) ([&]() { \
persistent c16 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c16, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return C16Array{ \
buf, \
wapp_misc_utils_va_args_count(c16, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c16, __VA_ARGS__) * 2), \
sizeof(c16) \
}; \
}())
#define wapp_c16_array_with_capacity(CAPACITY) ([&]() { \
persistent c16 buf[CAPACITY] = {}; \
return C16Array{buf, 0, CAPACITY, sizeof(c16)}; \
}())
#define wapp_c16_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_c16_array_pop(ARRAY_PTR) : \
c16{} \
)
#define wapp_c32_array(...) ([&]() { \
persistent c32 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c32, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return C32Array{ \
buf, \
wapp_misc_utils_va_args_count(c32, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c32, __VA_ARGS__) * 2), \
sizeof(c32) \
}; \
}())
#define wapp_c32_array_with_capacity(CAPACITY) ([&]() { \
persistent c32 buf[CAPACITY] = {}; \
return C32Array{buf, 0, CAPACITY, sizeof(c32)}; \
}())
#define wapp_c32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_c32_array_pop(ARRAY_PTR) : \
c32{} \
)
#define wapp_i8_array(...) ([&]() { \
persistent i8 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i8, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return I8Array{ \
buf, \
wapp_misc_utils_va_args_count(i8, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i8, __VA_ARGS__) * 2), \
sizeof(i8) \
}; \
}())
#define wapp_i8_array_with_capacity(CAPACITY) ([&]() { \
persistent i8 buf[CAPACITY] = {}; \
return I8Array{buf, 0, CAPACITY, sizeof(i8)}; \
}())
#define wapp_i8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_i8_array_pop(ARRAY_PTR) : \
i8{} \
)
#define wapp_i16_array(...) ([&]() { \
persistent i16 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i16, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return I16Array{ \
buf, \
wapp_misc_utils_va_args_count(i16, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i16, __VA_ARGS__) * 2), \
sizeof(i16) \
}; \
}())
#define wapp_i16_array_with_capacity(CAPACITY) ([&]() { \
persistent i16 buf[CAPACITY] = {}; \
return I16Array{buf, 0, CAPACITY, sizeof(i16)}; \
}())
#define wapp_i16_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_i16_array_pop(ARRAY_PTR) : \
i16{} \
)
#define wapp_i32_array(...) ([&]() { \
persistent i32 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i32, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return I32Array{ \
buf, \
wapp_misc_utils_va_args_count(i32, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i32, __VA_ARGS__) * 2), \
sizeof(i32) \
}; \
}())
#define wapp_i32_array_with_capacity(CAPACITY) ([&]() { \
persistent i32 buf[CAPACITY] = {}; \
return I32Array{buf, 0, CAPACITY, sizeof(i32)}; \
}())
#define wapp_i32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_i32_array_pop(ARRAY_PTR) : \
i32{} \
)
#define wapp_i64_array(...) ([&]() { \
persistent i64 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i64, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return I64Array{ \
buf, \
wapp_misc_utils_va_args_count(i64, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i64, __VA_ARGS__) * 2), \
sizeof(i64) \
}; \
}())
#define wapp_i64_array_with_capacity(CAPACITY) ([&]() { \
persistent i64 buf[CAPACITY] = {}; \
return I64Array{buf, 0, CAPACITY, sizeof(i64)}; \
}())
#define wapp_i64_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_i64_array_pop(ARRAY_PTR) : \
i64{} \
)
#define wapp_u8_array(...) ([&]() { \
persistent u8 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u8, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return U8Array{ \
buf, \
wapp_misc_utils_va_args_count(u8, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u8, __VA_ARGS__) * 2), \
sizeof(u8) \
}; \
}())
#define wapp_u8_array_with_capacity(CAPACITY) ([&]() { \
persistent u8 buf[CAPACITY] = {}; \
return U8Array{buf, 0, CAPACITY, sizeof(u8)}; \
}())
#define wapp_u8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_u8_array_pop(ARRAY_PTR) : \
u8{} \
)
#define wapp_u16_array(...) ([&]() { \
persistent u16 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u16, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return U16Array{ \
buf, \
wapp_misc_utils_va_args_count(u16, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u16, __VA_ARGS__) * 2), \
sizeof(u16) \
}; \
}())
#define wapp_u16_array_with_capacity(CAPACITY) ([&]() { \
persistent u16 buf[CAPACITY] = {}; \
return U16Array{buf, 0, CAPACITY, sizeof(u16)}; \
}())
#define wapp_u16_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_u16_array_pop(ARRAY_PTR) : \
u16{} \
)
#define wapp_u32_array(...) ([&]() { \
persistent u32 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u32, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return U32Array{ \
buf, \
wapp_misc_utils_va_args_count(u32, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u32, __VA_ARGS__) * 2), \
sizeof(u32) \
}; \
}())
#define wapp_u32_array_with_capacity(CAPACITY) ([&]() { \
persistent u32 buf[CAPACITY] = {}; \
return U32Array{buf, 0, CAPACITY, sizeof(u32)}; \
}())
#define wapp_u32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_u32_array_pop(ARRAY_PTR) : \
u32{} \
)
#define wapp_u64_array(...) ([&]() { \
persistent u64 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u64, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return U64Array{ \
buf, \
wapp_misc_utils_va_args_count(u64, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u64, __VA_ARGS__) * 2), \
sizeof(u64) \
}; \
}())
#define wapp_u64_array_with_capacity(CAPACITY) ([&]() { \
persistent u64 buf[CAPACITY] = {}; \
return U64Array{buf, 0, CAPACITY, sizeof(u64)}; \
}())
#define wapp_u64_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_u64_array_pop(ARRAY_PTR) : \
u64{} \
)
#define wapp_f32_array(...) ([&]() { \
persistent f32 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f32, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return F32Array{ \
buf, \
wapp_misc_utils_va_args_count(f32, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f32, __VA_ARGS__) * 2), \
sizeof(f32) \
}; \
}())
#define wapp_f32_array_with_capacity(CAPACITY) ([&]() { \
persistent f32 buf[CAPACITY] = {}; \
return F32Array{buf, 0, CAPACITY, sizeof(f32)}; \
}())
#define wapp_f32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_f32_array_pop(ARRAY_PTR) : \
f32{} \
)
#define wapp_f64_array(...) ([&]() { \
persistent f64 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f64, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return F64Array{ \
buf, \
wapp_misc_utils_va_args_count(f64, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f64, __VA_ARGS__) * 2), \
sizeof(f64) \
}; \
}())
#define wapp_f64_array_with_capacity(CAPACITY) ([&]() { \
persistent f64 buf[CAPACITY] = {}; \
return F64Array{buf, 0, CAPACITY, sizeof(f64)}; \
}())
#define wapp_f64_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_f64_array_pop(ARRAY_PTR) : \
f64{} \
)
#define wapp_f128_array(...) ([&]() { \
persistent f128 buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f128, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return F128Array{ \
buf, \
wapp_misc_utils_va_args_count(f128, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f128, __VA_ARGS__) * 2), \
sizeof(f128) \
}; \
}())
#define wapp_f128_array_with_capacity(CAPACITY) ([&]() { \
persistent f128 buf[CAPACITY] = {}; \
return F128Array{buf, 0, CAPACITY, sizeof(f128)}; \
}())
#define wapp_f128_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_f128_array_pop(ARRAY_PTR) : \
f128{} \
)
#define wapp_iptr_array(...) ([&]() { \
persistent iptr buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(iptr, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return IptrArray{ \
buf, \
wapp_misc_utils_va_args_count(iptr, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(iptr, __VA_ARGS__) * 2), \
sizeof(iptr) \
}; \
}())
#define wapp_iptr_array_with_capacity(CAPACITY) ([&]() { \
persistent iptr buf[CAPACITY] = {}; \
return IptrArray{buf, 0, CAPACITY, sizeof(iptr)}; \
}())
#define wapp_iptr_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_iptr_array_pop(ARRAY_PTR) : \
iptr{} \
)
#define wapp_uptr_array(...) ([&]() { \
persistent uptr buf[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(uptr, __VA_ARGS__) * 2)] = {__VA_ARGS__}; \
return UptrArray{ \
buf, \
wapp_misc_utils_va_args_count(uptr, __VA_ARGS__), \
wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(uptr, __VA_ARGS__) * 2), \
sizeof(uptr) \
}; \
}())
#define wapp_uptr_array_with_capacity(CAPACITY) ([&]() { \
persistent uptr buf[CAPACITY] = {}; \
return UptrArray{buf, 0, CAPACITY, sizeof(uptr)}; \
}())
#define wapp_uptr_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_uptr_array_pop(ARRAY_PTR) : \
uptr{} \
)
#else
#define wapp_str8_array(...) ((Str8Array){ \
.items = (Str8[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(Str8, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(Str8, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(Str8, __VA_ARGS__) * 2), \
.item_size = sizeof(Str8) \
})
#define wapp_str8_array_with_capacity(CAPACITY) ((Str8Array){.items = (Str8[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(Str8)})
#define wapp_str8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_str8_array_pop(ARRAY_PTR) : \
(Str8){0} \
)
#define wapp_void_ptr_array(...) ((VoidPArray){ \
.items = (void *[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(void *, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(void *, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(void *, __VA_ARGS__) * 2), \
.item_size = sizeof(void *) \
})
#define wapp_void_ptr_array_with_capacity(CAPACITY) ((VoidPArray){.items = (void *[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(void *)})
#define wapp_void_ptr_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_void_ptr_array_pop(ARRAY_PTR) : \
(void *){0} \
)
#define wapp_b32_array(...) ((B32Array){ \
.items = (b32[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(b32, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(b32, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(b32, __VA_ARGS__) * 2), \
.item_size = sizeof(b32) \
})
#define wapp_b32_array_with_capacity(CAPACITY) ((B32Array){.items = (b32[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(b32)})
#define wapp_b32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_b32_array_pop(ARRAY_PTR) : \
(b32){0} \
)
#define wapp_char_array(...) ((CharArray){ \
.items = (char[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(char, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(char, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(char, __VA_ARGS__) * 2), \
.item_size = sizeof(char) \
})
#define wapp_char_array_with_capacity(CAPACITY) ((CharArray){.items = (char[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(char)})
#define wapp_char_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_char_array_pop(ARRAY_PTR) : \
(char){0} \
)
#define wapp_c8_array(...) ((C8Array){ \
.items = (c8[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c8, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(c8, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c8, __VA_ARGS__) * 2), \
.item_size = sizeof(c8) \
})
#define wapp_c8_array_with_capacity(CAPACITY) ((C8Array){.items = (c8[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(c8)})
#define wapp_c8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_c8_array_pop(ARRAY_PTR) : \
(c8){0} \
)
#define wapp_c16_array(...) ((C16Array){ \
.items = (c16[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c16, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(c16, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c16, __VA_ARGS__) * 2), \
.item_size = sizeof(c16) \
})
#define wapp_c16_array_with_capacity(CAPACITY) ((C16Array){.items = (c16[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(c16)})
#define wapp_c16_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_c16_array_pop(ARRAY_PTR) : \
(c16){0} \
)
#define wapp_c32_array(...) ((C32Array){ \
.items = (c32[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c32, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(c32, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(c32, __VA_ARGS__) * 2), \
.item_size = sizeof(c32) \
})
#define wapp_c32_array_with_capacity(CAPACITY) ((C32Array){.items = (c32[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(c32)})
#define wapp_c32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_c32_array_pop(ARRAY_PTR) : \
(c32){0} \
)
#define wapp_i8_array(...) ((I8Array){ \
.items = (i8[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i8, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(i8, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i8, __VA_ARGS__) * 2), \
.item_size = sizeof(i8) \
})
#define wapp_i8_array_with_capacity(CAPACITY) ((I8Array){.items = (i8[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(i8)})
#define wapp_i8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_i8_array_pop(ARRAY_PTR) : \
(i8){0} \
)
#define wapp_i16_array(...) ((I16Array){ \
.items = (i16[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i16, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(i16, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i16, __VA_ARGS__) * 2), \
.item_size = sizeof(i16) \
})
#define wapp_i16_array_with_capacity(CAPACITY) ((I16Array){.items = (i16[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(i16)})
#define wapp_i16_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_i16_array_pop(ARRAY_PTR) : \
(i16){0} \
)
#define wapp_i32_array(...) ((I32Array){ \
.items = (i32[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i32, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(i32, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i32, __VA_ARGS__) * 2), \
.item_size = sizeof(i32) \
})
#define wapp_i32_array_with_capacity(CAPACITY) ((I32Array){.items = (i32[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(i32)})
#define wapp_i32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_i32_array_pop(ARRAY_PTR) : \
(i32){0} \
)
#define wapp_i64_array(...) ((I64Array){ \
.items = (i64[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i64, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(i64, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(i64, __VA_ARGS__) * 2), \
.item_size = sizeof(i64) \
})
#define wapp_i64_array_with_capacity(CAPACITY) ((I64Array){.items = (i64[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(i64)})
#define wapp_i64_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_i64_array_pop(ARRAY_PTR) : \
(i64){0} \
)
#define wapp_u8_array(...) ((U8Array){ \
.items = (u8[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u8, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(u8, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u8, __VA_ARGS__) * 2), \
.item_size = sizeof(u8) \
})
#define wapp_u8_array_with_capacity(CAPACITY) ((U8Array){.items = (u8[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(u8)})
#define wapp_u8_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_u8_array_pop(ARRAY_PTR) : \
(u8){0} \
)
#define wapp_u16_array(...) ((U16Array){ \
.items = (u16[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u16, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(u16, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u16, __VA_ARGS__) * 2), \
.item_size = sizeof(u16) \
})
#define wapp_u16_array_with_capacity(CAPACITY) ((U16Array){.items = (u16[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(u16)})
#define wapp_u16_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_u16_array_pop(ARRAY_PTR) : \
(u16){0} \
)
#define wapp_u32_array(...) ((U32Array){ \
.items = (u32[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u32, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(u32, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u32, __VA_ARGS__) * 2), \
.item_size = sizeof(u32) \
})
#define wapp_u32_array_with_capacity(CAPACITY) ((U32Array){.items = (u32[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(u32)})
#define wapp_u32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_u32_array_pop(ARRAY_PTR) : \
(u32){0} \
)
#define wapp_u64_array(...) ((U64Array){ \
.items = (u64[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u64, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(u64, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(u64, __VA_ARGS__) * 2), \
.item_size = sizeof(u64) \
})
#define wapp_u64_array_with_capacity(CAPACITY) ((U64Array){.items = (u64[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(u64)})
#define wapp_u64_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_u64_array_pop(ARRAY_PTR) : \
(u64){0} \
)
#define wapp_f32_array(...) ((F32Array){ \
.items = (f32[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f32, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(f32, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f32, __VA_ARGS__) * 2), \
.item_size = sizeof(f32) \
})
#define wapp_f32_array_with_capacity(CAPACITY) ((F32Array){.items = (f32[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(f32)})
#define wapp_f32_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_f32_array_pop(ARRAY_PTR) : \
(f32){0} \
)
#define wapp_f64_array(...) ((F64Array){ \
.items = (f64[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f64, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(f64, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f64, __VA_ARGS__) * 2), \
.item_size = sizeof(f64) \
})
#define wapp_f64_array_with_capacity(CAPACITY) ((F64Array){.items = (f64[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(f64)})
#define wapp_f64_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_f64_array_pop(ARRAY_PTR) : \
(f64){0} \
)
#define wapp_f128_array(...) ((F128Array){ \
.items = (f128[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f128, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(f128, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(f128, __VA_ARGS__) * 2), \
.item_size = sizeof(f128) \
})
#define wapp_f128_array_with_capacity(CAPACITY) ((F128Array){.items = (f128[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(f128)})
#define wapp_f128_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_f128_array_pop(ARRAY_PTR) : \
(f128){0} \
)
#define wapp_iptr_array(...) ((IptrArray){ \
.items = (iptr[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(iptr, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(iptr, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(iptr, __VA_ARGS__) * 2), \
.item_size = sizeof(iptr) \
})
#define wapp_iptr_array_with_capacity(CAPACITY) ((IptrArray){.items = (iptr[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(iptr)})
#define wapp_iptr_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_iptr_array_pop(ARRAY_PTR) : \
(iptr){0} \
)
#define wapp_uptr_array(...) ((UptrArray){ \
.items = (uptr[wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(uptr, __VA_ARGS__) * 2)]){__VA_ARGS__}, \
.count = wapp_misc_utils_va_args_count(uptr, __VA_ARGS__), \
.capacity = wapp_misc_utils_u64_round_up_pow2(wapp_misc_utils_va_args_count(uptr, __VA_ARGS__) * 2), \
.item_size = sizeof(uptr) \
})
#define wapp_uptr_array_with_capacity(CAPACITY) ((UptrArray){.items = (uptr[CAPACITY]){0}, .count = 0, .capacity = CAPACITY, .item_size = sizeof(uptr)})
#define wapp_uptr_array_pop(ARRAY_PTR) (ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \
*_uptr_array_pop(ARRAY_PTR) : \
(uptr){0} \
)
#endif // !WAPP_PLATFORM_CPP
typedef struct str8 Str8;
typedef struct Str8Array Str8Array;
struct Str8Array {
Str8 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct VoidPArray VoidPArray;
struct VoidPArray {
void * *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct B32Array B32Array;
struct B32Array {
b32 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct CharArray CharArray;
struct CharArray {
char *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct C8Array C8Array;
struct C8Array {
c8 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct C16Array C16Array;
struct C16Array {
c16 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct C32Array C32Array;
struct C32Array {
c32 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct I8Array I8Array;
struct I8Array {
i8 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct I16Array I16Array;
struct I16Array {
i16 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct I32Array I32Array;
struct I32Array {
i32 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct I64Array I64Array;
struct I64Array {
i64 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct U8Array U8Array;
struct U8Array {
u8 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct U16Array U16Array;
struct U16Array {
u16 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct U32Array U32Array;
struct U32Array {
u32 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct U64Array U64Array;
struct U64Array {
u64 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct F32Array F32Array;
struct F32Array {
f32 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct F64Array F64Array;
struct F64Array {
f64 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct F128Array F128Array;
struct F128Array {
f128 *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct IptrArray IptrArray;
struct IptrArray {
iptr *items;
u64 count;
u64 capacity;
u64 item_size;
};
typedef struct UptrArray UptrArray;
struct UptrArray {
uptr *items;
u64 count;
u64 capacity;
u64 item_size;
};
Str8 *wapp_str8_array_get(const Str8Array *array, u64 index);
void wapp_str8_array_set(Str8Array *array, u64 index, Str8 *item);
void wapp_str8_array_append_capped(Str8Array *array, Str8 *item);
void wapp_str8_array_extend_capped(Str8Array *array, const Str8Array *other);
void wapp_str8_array_clear(Str8Array *array);
void wapp_str8_array_copy_capped(const Str8Array *src, Str8Array *dst);
Str8Array *wapp_str8_array_append_alloc(const Allocator *allocator, Str8Array *array, Str8 *item);
Str8Array *wapp_str8_array_extend_alloc(const Allocator *allocator, Str8Array *array, const Str8Array *other);
Str8Array *wapp_str8_array_copy_alloc(const Allocator *allocator, const Str8Array *src, Str8Array *dst);
Str8 *_str8_array_pop(Str8Array *array);
void * *wapp_void_ptr_array_get(const VoidPArray *array, u64 index);
void wapp_void_ptr_array_set(VoidPArray *array, u64 index, void * *item);
void wapp_void_ptr_array_append_capped(VoidPArray *array, void * *item);
void wapp_void_ptr_array_extend_capped(VoidPArray *array, const VoidPArray *other);
void wapp_void_ptr_array_clear(VoidPArray *array);
void wapp_void_ptr_array_copy_capped(const VoidPArray *src, VoidPArray *dst);
VoidPArray *wapp_void_ptr_array_append_alloc(const Allocator *allocator, VoidPArray *array, void * *item);
VoidPArray *wapp_void_ptr_array_extend_alloc(const Allocator *allocator, VoidPArray *array, const VoidPArray *other);
VoidPArray *wapp_void_ptr_array_copy_alloc(const Allocator *allocator, const VoidPArray *src, VoidPArray *dst);
void * *_void_ptr_array_pop(VoidPArray *array);
b32 *wapp_b32_array_get(const B32Array *array, u64 index);
void wapp_b32_array_set(B32Array *array, u64 index, b32 *item);
void wapp_b32_array_append_capped(B32Array *array, b32 *item);
void wapp_b32_array_extend_capped(B32Array *array, const B32Array *other);
void wapp_b32_array_clear(B32Array *array);
void wapp_b32_array_copy_capped(const B32Array *src, B32Array *dst);
B32Array *wapp_b32_array_append_alloc(const Allocator *allocator, B32Array *array, b32 *item);
B32Array *wapp_b32_array_extend_alloc(const Allocator *allocator, B32Array *array, const B32Array *other);
B32Array *wapp_b32_array_copy_alloc(const Allocator *allocator, const B32Array *src, B32Array *dst);
b32 *_b32_array_pop(B32Array *array);
char *wapp_char_array_get(const CharArray *array, u64 index);
void wapp_char_array_set(CharArray *array, u64 index, char *item);
void wapp_char_array_append_capped(CharArray *array, char *item);
void wapp_char_array_extend_capped(CharArray *array, const CharArray *other);
void wapp_char_array_clear(CharArray *array);
void wapp_char_array_copy_capped(const CharArray *src, CharArray *dst);
CharArray *wapp_char_array_append_alloc(const Allocator *allocator, CharArray *array, char *item);
CharArray *wapp_char_array_extend_alloc(const Allocator *allocator, CharArray *array, const CharArray *other);
CharArray *wapp_char_array_copy_alloc(const Allocator *allocator, const CharArray *src, CharArray *dst);
char *_char_array_pop(CharArray *array);
c8 *wapp_c8_array_get(const C8Array *array, u64 index);
void wapp_c8_array_set(C8Array *array, u64 index, c8 *item);
void wapp_c8_array_append_capped(C8Array *array, c8 *item);
void wapp_c8_array_extend_capped(C8Array *array, const C8Array *other);
void wapp_c8_array_clear(C8Array *array);
void wapp_c8_array_copy_capped(const C8Array *src, C8Array *dst);
C8Array *wapp_c8_array_append_alloc(const Allocator *allocator, C8Array *array, c8 *item);
C8Array *wapp_c8_array_extend_alloc(const Allocator *allocator, C8Array *array, const C8Array *other);
C8Array *wapp_c8_array_copy_alloc(const Allocator *allocator, const C8Array *src, C8Array *dst);
c8 *_c8_array_pop(C8Array *array);
c16 *wapp_c16_array_get(const C16Array *array, u64 index);
void wapp_c16_array_set(C16Array *array, u64 index, c16 *item);
void wapp_c16_array_append_capped(C16Array *array, c16 *item);
void wapp_c16_array_extend_capped(C16Array *array, const C16Array *other);
void wapp_c16_array_clear(C16Array *array);
void wapp_c16_array_copy_capped(const C16Array *src, C16Array *dst);
C16Array *wapp_c16_array_append_alloc(const Allocator *allocator, C16Array *array, c16 *item);
C16Array *wapp_c16_array_extend_alloc(const Allocator *allocator, C16Array *array, const C16Array *other);
C16Array *wapp_c16_array_copy_alloc(const Allocator *allocator, const C16Array *src, C16Array *dst);
c16 *_c16_array_pop(C16Array *array);
c32 *wapp_c32_array_get(const C32Array *array, u64 index);
void wapp_c32_array_set(C32Array *array, u64 index, c32 *item);
void wapp_c32_array_append_capped(C32Array *array, c32 *item);
void wapp_c32_array_extend_capped(C32Array *array, const C32Array *other);
void wapp_c32_array_clear(C32Array *array);
void wapp_c32_array_copy_capped(const C32Array *src, C32Array *dst);
C32Array *wapp_c32_array_append_alloc(const Allocator *allocator, C32Array *array, c32 *item);
C32Array *wapp_c32_array_extend_alloc(const Allocator *allocator, C32Array *array, const C32Array *other);
C32Array *wapp_c32_array_copy_alloc(const Allocator *allocator, const C32Array *src, C32Array *dst);
c32 *_c32_array_pop(C32Array *array);
i8 *wapp_i8_array_get(const I8Array *array, u64 index);
void wapp_i8_array_set(I8Array *array, u64 index, i8 *item);
void wapp_i8_array_append_capped(I8Array *array, i8 *item);
void wapp_i8_array_extend_capped(I8Array *array, const I8Array *other);
void wapp_i8_array_clear(I8Array *array);
void wapp_i8_array_copy_capped(const I8Array *src, I8Array *dst);
I8Array *wapp_i8_array_append_alloc(const Allocator *allocator, I8Array *array, i8 *item);
I8Array *wapp_i8_array_extend_alloc(const Allocator *allocator, I8Array *array, const I8Array *other);
I8Array *wapp_i8_array_copy_alloc(const Allocator *allocator, const I8Array *src, I8Array *dst);
i8 *_i8_array_pop(I8Array *array);
i16 *wapp_i16_array_get(const I16Array *array, u64 index);
void wapp_i16_array_set(I16Array *array, u64 index, i16 *item);
void wapp_i16_array_append_capped(I16Array *array, i16 *item);
void wapp_i16_array_extend_capped(I16Array *array, const I16Array *other);
void wapp_i16_array_clear(I16Array *array);
void wapp_i16_array_copy_capped(const I16Array *src, I16Array *dst);
I16Array *wapp_i16_array_append_alloc(const Allocator *allocator, I16Array *array, i16 *item);
I16Array *wapp_i16_array_extend_alloc(const Allocator *allocator, I16Array *array, const I16Array *other);
I16Array *wapp_i16_array_copy_alloc(const Allocator *allocator, const I16Array *src, I16Array *dst);
i16 *_i16_array_pop(I16Array *array);
i32 *wapp_i32_array_get(const I32Array *array, u64 index);
void wapp_i32_array_set(I32Array *array, u64 index, i32 *item);
void wapp_i32_array_append_capped(I32Array *array, i32 *item);
void wapp_i32_array_extend_capped(I32Array *array, const I32Array *other);
void wapp_i32_array_clear(I32Array *array);
void wapp_i32_array_copy_capped(const I32Array *src, I32Array *dst);
I32Array *wapp_i32_array_append_alloc(const Allocator *allocator, I32Array *array, i32 *item);
I32Array *wapp_i32_array_extend_alloc(const Allocator *allocator, I32Array *array, const I32Array *other);
I32Array *wapp_i32_array_copy_alloc(const Allocator *allocator, const I32Array *src, I32Array *dst);
i32 *_i32_array_pop(I32Array *array);
i64 *wapp_i64_array_get(const I64Array *array, u64 index);
void wapp_i64_array_set(I64Array *array, u64 index, i64 *item);
void wapp_i64_array_append_capped(I64Array *array, i64 *item);
void wapp_i64_array_extend_capped(I64Array *array, const I64Array *other);
void wapp_i64_array_clear(I64Array *array);
void wapp_i64_array_copy_capped(const I64Array *src, I64Array *dst);
I64Array *wapp_i64_array_append_alloc(const Allocator *allocator, I64Array *array, i64 *item);
I64Array *wapp_i64_array_extend_alloc(const Allocator *allocator, I64Array *array, const I64Array *other);
I64Array *wapp_i64_array_copy_alloc(const Allocator *allocator, const I64Array *src, I64Array *dst);
i64 *_i64_array_pop(I64Array *array);
u8 *wapp_u8_array_get(const U8Array *array, u64 index);
void wapp_u8_array_set(U8Array *array, u64 index, u8 *item);
void wapp_u8_array_append_capped(U8Array *array, u8 *item);
void wapp_u8_array_extend_capped(U8Array *array, const U8Array *other);
void wapp_u8_array_clear(U8Array *array);
void wapp_u8_array_copy_capped(const U8Array *src, U8Array *dst);
U8Array *wapp_u8_array_append_alloc(const Allocator *allocator, U8Array *array, u8 *item);
U8Array *wapp_u8_array_extend_alloc(const Allocator *allocator, U8Array *array, const U8Array *other);
U8Array *wapp_u8_array_copy_alloc(const Allocator *allocator, const U8Array *src, U8Array *dst);
u8 *_u8_array_pop(U8Array *array);
u16 *wapp_u16_array_get(const U16Array *array, u64 index);
void wapp_u16_array_set(U16Array *array, u64 index, u16 *item);
void wapp_u16_array_append_capped(U16Array *array, u16 *item);
void wapp_u16_array_extend_capped(U16Array *array, const U16Array *other);
void wapp_u16_array_clear(U16Array *array);
void wapp_u16_array_copy_capped(const U16Array *src, U16Array *dst);
U16Array *wapp_u16_array_append_alloc(const Allocator *allocator, U16Array *array, u16 *item);
U16Array *wapp_u16_array_extend_alloc(const Allocator *allocator, U16Array *array, const U16Array *other);
U16Array *wapp_u16_array_copy_alloc(const Allocator *allocator, const U16Array *src, U16Array *dst);
u16 *_u16_array_pop(U16Array *array);
u32 *wapp_u32_array_get(const U32Array *array, u64 index);
void wapp_u32_array_set(U32Array *array, u64 index, u32 *item);
void wapp_u32_array_append_capped(U32Array *array, u32 *item);
void wapp_u32_array_extend_capped(U32Array *array, const U32Array *other);
void wapp_u32_array_clear(U32Array *array);
void wapp_u32_array_copy_capped(const U32Array *src, U32Array *dst);
U32Array *wapp_u32_array_append_alloc(const Allocator *allocator, U32Array *array, u32 *item);
U32Array *wapp_u32_array_extend_alloc(const Allocator *allocator, U32Array *array, const U32Array *other);
U32Array *wapp_u32_array_copy_alloc(const Allocator *allocator, const U32Array *src, U32Array *dst);
u32 *_u32_array_pop(U32Array *array);
u64 *wapp_u64_array_get(const U64Array *array, u64 index);
void wapp_u64_array_set(U64Array *array, u64 index, u64 *item);
void wapp_u64_array_append_capped(U64Array *array, u64 *item);
void wapp_u64_array_extend_capped(U64Array *array, const U64Array *other);
void wapp_u64_array_clear(U64Array *array);
void wapp_u64_array_copy_capped(const U64Array *src, U64Array *dst);
U64Array *wapp_u64_array_append_alloc(const Allocator *allocator, U64Array *array, u64 *item);
U64Array *wapp_u64_array_extend_alloc(const Allocator *allocator, U64Array *array, const U64Array *other);
U64Array *wapp_u64_array_copy_alloc(const Allocator *allocator, const U64Array *src, U64Array *dst);
u64 *_u64_array_pop(U64Array *array);
f32 *wapp_f32_array_get(const F32Array *array, u64 index);
void wapp_f32_array_set(F32Array *array, u64 index, f32 *item);
void wapp_f32_array_append_capped(F32Array *array, f32 *item);
void wapp_f32_array_extend_capped(F32Array *array, const F32Array *other);
void wapp_f32_array_clear(F32Array *array);
void wapp_f32_array_copy_capped(const F32Array *src, F32Array *dst);
F32Array *wapp_f32_array_append_alloc(const Allocator *allocator, F32Array *array, f32 *item);
F32Array *wapp_f32_array_extend_alloc(const Allocator *allocator, F32Array *array, const F32Array *other);
F32Array *wapp_f32_array_copy_alloc(const Allocator *allocator, const F32Array *src, F32Array *dst);
f32 *_f32_array_pop(F32Array *array);
f64 *wapp_f64_array_get(const F64Array *array, u64 index);
void wapp_f64_array_set(F64Array *array, u64 index, f64 *item);
void wapp_f64_array_append_capped(F64Array *array, f64 *item);
void wapp_f64_array_extend_capped(F64Array *array, const F64Array *other);
void wapp_f64_array_clear(F64Array *array);
void wapp_f64_array_copy_capped(const F64Array *src, F64Array *dst);
F64Array *wapp_f64_array_append_alloc(const Allocator *allocator, F64Array *array, f64 *item);
F64Array *wapp_f64_array_extend_alloc(const Allocator *allocator, F64Array *array, const F64Array *other);
F64Array *wapp_f64_array_copy_alloc(const Allocator *allocator, const F64Array *src, F64Array *dst);
f64 *_f64_array_pop(F64Array *array);
f128 *wapp_f128_array_get(const F128Array *array, u64 index);
void wapp_f128_array_set(F128Array *array, u64 index, f128 *item);
void wapp_f128_array_append_capped(F128Array *array, f128 *item);
void wapp_f128_array_extend_capped(F128Array *array, const F128Array *other);
void wapp_f128_array_clear(F128Array *array);
void wapp_f128_array_copy_capped(const F128Array *src, F128Array *dst);
F128Array *wapp_f128_array_append_alloc(const Allocator *allocator, F128Array *array, f128 *item);
F128Array *wapp_f128_array_extend_alloc(const Allocator *allocator, F128Array *array, const F128Array *other);
F128Array *wapp_f128_array_copy_alloc(const Allocator *allocator, const F128Array *src, F128Array *dst);
f128 *_f128_array_pop(F128Array *array);
iptr *wapp_iptr_array_get(const IptrArray *array, u64 index);
void wapp_iptr_array_set(IptrArray *array, u64 index, iptr *item);
void wapp_iptr_array_append_capped(IptrArray *array, iptr *item);
void wapp_iptr_array_extend_capped(IptrArray *array, const IptrArray *other);
void wapp_iptr_array_clear(IptrArray *array);
void wapp_iptr_array_copy_capped(const IptrArray *src, IptrArray *dst);
IptrArray *wapp_iptr_array_append_alloc(const Allocator *allocator, IptrArray *array, iptr *item);
IptrArray *wapp_iptr_array_extend_alloc(const Allocator *allocator, IptrArray *array, const IptrArray *other);
IptrArray *wapp_iptr_array_copy_alloc(const Allocator *allocator, const IptrArray *src, IptrArray *dst);
iptr *_iptr_array_pop(IptrArray *array);
uptr *wapp_uptr_array_get(const UptrArray *array, u64 index);
void wapp_uptr_array_set(UptrArray *array, u64 index, uptr *item);
void wapp_uptr_array_append_capped(UptrArray *array, uptr *item);
void wapp_uptr_array_extend_capped(UptrArray *array, const UptrArray *other);
void wapp_uptr_array_clear(UptrArray *array);
void wapp_uptr_array_copy_capped(const UptrArray *src, UptrArray *dst);
UptrArray *wapp_uptr_array_append_alloc(const Allocator *allocator, UptrArray *array, uptr *item);
UptrArray *wapp_uptr_array_extend_alloc(const Allocator *allocator, UptrArray *array, const UptrArray *other);
UptrArray *wapp_uptr_array_copy_alloc(const Allocator *allocator, const UptrArray *src, UptrArray *dst);
uptr *_uptr_array_pop(UptrArray *array);
VoidPArray *_array_alloc_capacity(const Allocator *allocator, u64 capacity, u64 item_size);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !ARRAY_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,507 @@
/**
* THIS FILE IS AUTOMATICALLY GENERATED. ANY MODIFICATIONS TO IT WILL BE OVERWRITTEN
*/
#ifndef DBL_LIST_H
#define DBL_LIST_H
#include "../../common/aliases/aliases.h"
#include "../../common/aliases/aliases.h"
#include "../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_CPP
#define wapp_str8_list_node(ITEM_PTR) Str8Node{ITEM_PTR, nullptr, nullptr}
#define wapp_void_ptr_list_node(ITEM_PTR) VoidPNode{ITEM_PTR, nullptr, nullptr}
#define wapp_b32_list_node(ITEM_PTR) B32Node{ITEM_PTR, nullptr, nullptr}
#define wapp_char_list_node(ITEM_PTR) CharNode{ITEM_PTR, nullptr, nullptr}
#define wapp_c8_list_node(ITEM_PTR) C8Node{ITEM_PTR, nullptr, nullptr}
#define wapp_c16_list_node(ITEM_PTR) C16Node{ITEM_PTR, nullptr, nullptr}
#define wapp_c32_list_node(ITEM_PTR) C32Node{ITEM_PTR, nullptr, nullptr}
#define wapp_i8_list_node(ITEM_PTR) I8Node{ITEM_PTR, nullptr, nullptr}
#define wapp_i16_list_node(ITEM_PTR) I16Node{ITEM_PTR, nullptr, nullptr}
#define wapp_i32_list_node(ITEM_PTR) I32Node{ITEM_PTR, nullptr, nullptr}
#define wapp_i64_list_node(ITEM_PTR) I64Node{ITEM_PTR, nullptr, nullptr}
#define wapp_u8_list_node(ITEM_PTR) U8Node{ITEM_PTR, nullptr, nullptr}
#define wapp_u16_list_node(ITEM_PTR) U16Node{ITEM_PTR, nullptr, nullptr}
#define wapp_u32_list_node(ITEM_PTR) U32Node{ITEM_PTR, nullptr, nullptr}
#define wapp_u64_list_node(ITEM_PTR) U64Node{ITEM_PTR, nullptr, nullptr}
#define wapp_f32_list_node(ITEM_PTR) F32Node{ITEM_PTR, nullptr, nullptr}
#define wapp_f64_list_node(ITEM_PTR) F64Node{ITEM_PTR, nullptr, nullptr}
#define wapp_f128_list_node(ITEM_PTR) F128Node{ITEM_PTR, nullptr, nullptr}
#define wapp_iptr_list_node(ITEM_PTR) IptrNode{ITEM_PTR, nullptr, nullptr}
#define wapp_uptr_list_node(ITEM_PTR) UptrNode{ITEM_PTR, nullptr, nullptr}
#else
#define wapp_str8_list_node(ITEM_PTR) ((Str8Node){.item = ITEM_PTR})
#define wapp_void_ptr_list_node(ITEM_PTR) ((VoidPNode){.item = ITEM_PTR})
#define wapp_b32_list_node(ITEM_PTR) ((B32Node){.item = ITEM_PTR})
#define wapp_char_list_node(ITEM_PTR) ((CharNode){.item = ITEM_PTR})
#define wapp_c8_list_node(ITEM_PTR) ((C8Node){.item = ITEM_PTR})
#define wapp_c16_list_node(ITEM_PTR) ((C16Node){.item = ITEM_PTR})
#define wapp_c32_list_node(ITEM_PTR) ((C32Node){.item = ITEM_PTR})
#define wapp_i8_list_node(ITEM_PTR) ((I8Node){.item = ITEM_PTR})
#define wapp_i16_list_node(ITEM_PTR) ((I16Node){.item = ITEM_PTR})
#define wapp_i32_list_node(ITEM_PTR) ((I32Node){.item = ITEM_PTR})
#define wapp_i64_list_node(ITEM_PTR) ((I64Node){.item = ITEM_PTR})
#define wapp_u8_list_node(ITEM_PTR) ((U8Node){.item = ITEM_PTR})
#define wapp_u16_list_node(ITEM_PTR) ((U16Node){.item = ITEM_PTR})
#define wapp_u32_list_node(ITEM_PTR) ((U32Node){.item = ITEM_PTR})
#define wapp_u64_list_node(ITEM_PTR) ((U64Node){.item = ITEM_PTR})
#define wapp_f32_list_node(ITEM_PTR) ((F32Node){.item = ITEM_PTR})
#define wapp_f64_list_node(ITEM_PTR) ((F64Node){.item = ITEM_PTR})
#define wapp_f128_list_node(ITEM_PTR) ((F128Node){.item = ITEM_PTR})
#define wapp_iptr_list_node(ITEM_PTR) ((IptrNode){.item = ITEM_PTR})
#define wapp_uptr_list_node(ITEM_PTR) ((UptrNode){.item = ITEM_PTR})
#endif // !WAPP_PLATFORM_CPP
typedef struct str8 Str8;
typedef struct Str8Node Str8Node;
struct Str8Node {
Str8 *item;
Str8Node *prev;
Str8Node *next;
};
typedef struct Str8List Str8List;
struct Str8List {
Str8Node *first;
Str8Node *last;
u64 node_count;
};
typedef struct VoidPNode VoidPNode;
struct VoidPNode {
void * *item;
VoidPNode *prev;
VoidPNode *next;
};
typedef struct VoidPList VoidPList;
struct VoidPList {
VoidPNode *first;
VoidPNode *last;
u64 node_count;
};
typedef struct B32Node B32Node;
struct B32Node {
b32 *item;
B32Node *prev;
B32Node *next;
};
typedef struct B32List B32List;
struct B32List {
B32Node *first;
B32Node *last;
u64 node_count;
};
typedef struct CharNode CharNode;
struct CharNode {
char *item;
CharNode *prev;
CharNode *next;
};
typedef struct CharList CharList;
struct CharList {
CharNode *first;
CharNode *last;
u64 node_count;
};
typedef struct C8Node C8Node;
struct C8Node {
c8 *item;
C8Node *prev;
C8Node *next;
};
typedef struct C8List C8List;
struct C8List {
C8Node *first;
C8Node *last;
u64 node_count;
};
typedef struct C16Node C16Node;
struct C16Node {
c16 *item;
C16Node *prev;
C16Node *next;
};
typedef struct C16List C16List;
struct C16List {
C16Node *first;
C16Node *last;
u64 node_count;
};
typedef struct C32Node C32Node;
struct C32Node {
c32 *item;
C32Node *prev;
C32Node *next;
};
typedef struct C32List C32List;
struct C32List {
C32Node *first;
C32Node *last;
u64 node_count;
};
typedef struct I8Node I8Node;
struct I8Node {
i8 *item;
I8Node *prev;
I8Node *next;
};
typedef struct I8List I8List;
struct I8List {
I8Node *first;
I8Node *last;
u64 node_count;
};
typedef struct I16Node I16Node;
struct I16Node {
i16 *item;
I16Node *prev;
I16Node *next;
};
typedef struct I16List I16List;
struct I16List {
I16Node *first;
I16Node *last;
u64 node_count;
};
typedef struct I32Node I32Node;
struct I32Node {
i32 *item;
I32Node *prev;
I32Node *next;
};
typedef struct I32List I32List;
struct I32List {
I32Node *first;
I32Node *last;
u64 node_count;
};
typedef struct I64Node I64Node;
struct I64Node {
i64 *item;
I64Node *prev;
I64Node *next;
};
typedef struct I64List I64List;
struct I64List {
I64Node *first;
I64Node *last;
u64 node_count;
};
typedef struct U8Node U8Node;
struct U8Node {
u8 *item;
U8Node *prev;
U8Node *next;
};
typedef struct U8List U8List;
struct U8List {
U8Node *first;
U8Node *last;
u64 node_count;
};
typedef struct U16Node U16Node;
struct U16Node {
u16 *item;
U16Node *prev;
U16Node *next;
};
typedef struct U16List U16List;
struct U16List {
U16Node *first;
U16Node *last;
u64 node_count;
};
typedef struct U32Node U32Node;
struct U32Node {
u32 *item;
U32Node *prev;
U32Node *next;
};
typedef struct U32List U32List;
struct U32List {
U32Node *first;
U32Node *last;
u64 node_count;
};
typedef struct U64Node U64Node;
struct U64Node {
u64 *item;
U64Node *prev;
U64Node *next;
};
typedef struct U64List U64List;
struct U64List {
U64Node *first;
U64Node *last;
u64 node_count;
};
typedef struct F32Node F32Node;
struct F32Node {
f32 *item;
F32Node *prev;
F32Node *next;
};
typedef struct F32List F32List;
struct F32List {
F32Node *first;
F32Node *last;
u64 node_count;
};
typedef struct F64Node F64Node;
struct F64Node {
f64 *item;
F64Node *prev;
F64Node *next;
};
typedef struct F64List F64List;
struct F64List {
F64Node *first;
F64Node *last;
u64 node_count;
};
typedef struct F128Node F128Node;
struct F128Node {
f128 *item;
F128Node *prev;
F128Node *next;
};
typedef struct F128List F128List;
struct F128List {
F128Node *first;
F128Node *last;
u64 node_count;
};
typedef struct IptrNode IptrNode;
struct IptrNode {
iptr *item;
IptrNode *prev;
IptrNode *next;
};
typedef struct IptrList IptrList;
struct IptrList {
IptrNode *first;
IptrNode *last;
u64 node_count;
};
typedef struct UptrNode UptrNode;
struct UptrNode {
uptr *item;
UptrNode *prev;
UptrNode *next;
};
typedef struct UptrList UptrList;
struct UptrList {
UptrNode *first;
UptrNode *last;
u64 node_count;
};
Str8Node *wapp_str8_list_get(const Str8List *list, u64 index);
void wapp_str8_list_push_front(Str8List *list, Str8Node *node);
void wapp_str8_list_push_back(Str8List *list, Str8Node *node);
void wapp_str8_list_insert(Str8List *list, Str8Node *node, u64 index);
Str8Node *wapp_str8_list_pop_front(Str8List *list);
Str8Node *wapp_str8_list_pop_back(Str8List *list);
Str8Node *wapp_str8_list_remove(Str8List *list, u64 index);
void wapp_str8_list_empty(Str8List *list);
VoidPNode *wapp_void_ptr_list_get(const VoidPList *list, u64 index);
void wapp_void_ptr_list_push_front(VoidPList *list, VoidPNode *node);
void wapp_void_ptr_list_push_back(VoidPList *list, VoidPNode *node);
void wapp_void_ptr_list_insert(VoidPList *list, VoidPNode *node, u64 index);
VoidPNode *wapp_void_ptr_list_pop_front(VoidPList *list);
VoidPNode *wapp_void_ptr_list_pop_back(VoidPList *list);
VoidPNode *wapp_void_ptr_list_remove(VoidPList *list, u64 index);
void wapp_void_ptr_list_empty(VoidPList *list);
B32Node *wapp_b32_list_get(const B32List *list, u64 index);
void wapp_b32_list_push_front(B32List *list, B32Node *node);
void wapp_b32_list_push_back(B32List *list, B32Node *node);
void wapp_b32_list_insert(B32List *list, B32Node *node, u64 index);
B32Node *wapp_b32_list_pop_front(B32List *list);
B32Node *wapp_b32_list_pop_back(B32List *list);
B32Node *wapp_b32_list_remove(B32List *list, u64 index);
void wapp_b32_list_empty(B32List *list);
CharNode *wapp_char_list_get(const CharList *list, u64 index);
void wapp_char_list_push_front(CharList *list, CharNode *node);
void wapp_char_list_push_back(CharList *list, CharNode *node);
void wapp_char_list_insert(CharList *list, CharNode *node, u64 index);
CharNode *wapp_char_list_pop_front(CharList *list);
CharNode *wapp_char_list_pop_back(CharList *list);
CharNode *wapp_char_list_remove(CharList *list, u64 index);
void wapp_char_list_empty(CharList *list);
C8Node *wapp_c8_list_get(const C8List *list, u64 index);
void wapp_c8_list_push_front(C8List *list, C8Node *node);
void wapp_c8_list_push_back(C8List *list, C8Node *node);
void wapp_c8_list_insert(C8List *list, C8Node *node, u64 index);
C8Node *wapp_c8_list_pop_front(C8List *list);
C8Node *wapp_c8_list_pop_back(C8List *list);
C8Node *wapp_c8_list_remove(C8List *list, u64 index);
void wapp_c8_list_empty(C8List *list);
C16Node *wapp_c16_list_get(const C16List *list, u64 index);
void wapp_c16_list_push_front(C16List *list, C16Node *node);
void wapp_c16_list_push_back(C16List *list, C16Node *node);
void wapp_c16_list_insert(C16List *list, C16Node *node, u64 index);
C16Node *wapp_c16_list_pop_front(C16List *list);
C16Node *wapp_c16_list_pop_back(C16List *list);
C16Node *wapp_c16_list_remove(C16List *list, u64 index);
void wapp_c16_list_empty(C16List *list);
C32Node *wapp_c32_list_get(const C32List *list, u64 index);
void wapp_c32_list_push_front(C32List *list, C32Node *node);
void wapp_c32_list_push_back(C32List *list, C32Node *node);
void wapp_c32_list_insert(C32List *list, C32Node *node, u64 index);
C32Node *wapp_c32_list_pop_front(C32List *list);
C32Node *wapp_c32_list_pop_back(C32List *list);
C32Node *wapp_c32_list_remove(C32List *list, u64 index);
void wapp_c32_list_empty(C32List *list);
I8Node *wapp_i8_list_get(const I8List *list, u64 index);
void wapp_i8_list_push_front(I8List *list, I8Node *node);
void wapp_i8_list_push_back(I8List *list, I8Node *node);
void wapp_i8_list_insert(I8List *list, I8Node *node, u64 index);
I8Node *wapp_i8_list_pop_front(I8List *list);
I8Node *wapp_i8_list_pop_back(I8List *list);
I8Node *wapp_i8_list_remove(I8List *list, u64 index);
void wapp_i8_list_empty(I8List *list);
I16Node *wapp_i16_list_get(const I16List *list, u64 index);
void wapp_i16_list_push_front(I16List *list, I16Node *node);
void wapp_i16_list_push_back(I16List *list, I16Node *node);
void wapp_i16_list_insert(I16List *list, I16Node *node, u64 index);
I16Node *wapp_i16_list_pop_front(I16List *list);
I16Node *wapp_i16_list_pop_back(I16List *list);
I16Node *wapp_i16_list_remove(I16List *list, u64 index);
void wapp_i16_list_empty(I16List *list);
I32Node *wapp_i32_list_get(const I32List *list, u64 index);
void wapp_i32_list_push_front(I32List *list, I32Node *node);
void wapp_i32_list_push_back(I32List *list, I32Node *node);
void wapp_i32_list_insert(I32List *list, I32Node *node, u64 index);
I32Node *wapp_i32_list_pop_front(I32List *list);
I32Node *wapp_i32_list_pop_back(I32List *list);
I32Node *wapp_i32_list_remove(I32List *list, u64 index);
void wapp_i32_list_empty(I32List *list);
I64Node *wapp_i64_list_get(const I64List *list, u64 index);
void wapp_i64_list_push_front(I64List *list, I64Node *node);
void wapp_i64_list_push_back(I64List *list, I64Node *node);
void wapp_i64_list_insert(I64List *list, I64Node *node, u64 index);
I64Node *wapp_i64_list_pop_front(I64List *list);
I64Node *wapp_i64_list_pop_back(I64List *list);
I64Node *wapp_i64_list_remove(I64List *list, u64 index);
void wapp_i64_list_empty(I64List *list);
U8Node *wapp_u8_list_get(const U8List *list, u64 index);
void wapp_u8_list_push_front(U8List *list, U8Node *node);
void wapp_u8_list_push_back(U8List *list, U8Node *node);
void wapp_u8_list_insert(U8List *list, U8Node *node, u64 index);
U8Node *wapp_u8_list_pop_front(U8List *list);
U8Node *wapp_u8_list_pop_back(U8List *list);
U8Node *wapp_u8_list_remove(U8List *list, u64 index);
void wapp_u8_list_empty(U8List *list);
U16Node *wapp_u16_list_get(const U16List *list, u64 index);
void wapp_u16_list_push_front(U16List *list, U16Node *node);
void wapp_u16_list_push_back(U16List *list, U16Node *node);
void wapp_u16_list_insert(U16List *list, U16Node *node, u64 index);
U16Node *wapp_u16_list_pop_front(U16List *list);
U16Node *wapp_u16_list_pop_back(U16List *list);
U16Node *wapp_u16_list_remove(U16List *list, u64 index);
void wapp_u16_list_empty(U16List *list);
U32Node *wapp_u32_list_get(const U32List *list, u64 index);
void wapp_u32_list_push_front(U32List *list, U32Node *node);
void wapp_u32_list_push_back(U32List *list, U32Node *node);
void wapp_u32_list_insert(U32List *list, U32Node *node, u64 index);
U32Node *wapp_u32_list_pop_front(U32List *list);
U32Node *wapp_u32_list_pop_back(U32List *list);
U32Node *wapp_u32_list_remove(U32List *list, u64 index);
void wapp_u32_list_empty(U32List *list);
U64Node *wapp_u64_list_get(const U64List *list, u64 index);
void wapp_u64_list_push_front(U64List *list, U64Node *node);
void wapp_u64_list_push_back(U64List *list, U64Node *node);
void wapp_u64_list_insert(U64List *list, U64Node *node, u64 index);
U64Node *wapp_u64_list_pop_front(U64List *list);
U64Node *wapp_u64_list_pop_back(U64List *list);
U64Node *wapp_u64_list_remove(U64List *list, u64 index);
void wapp_u64_list_empty(U64List *list);
F32Node *wapp_f32_list_get(const F32List *list, u64 index);
void wapp_f32_list_push_front(F32List *list, F32Node *node);
void wapp_f32_list_push_back(F32List *list, F32Node *node);
void wapp_f32_list_insert(F32List *list, F32Node *node, u64 index);
F32Node *wapp_f32_list_pop_front(F32List *list);
F32Node *wapp_f32_list_pop_back(F32List *list);
F32Node *wapp_f32_list_remove(F32List *list, u64 index);
void wapp_f32_list_empty(F32List *list);
F64Node *wapp_f64_list_get(const F64List *list, u64 index);
void wapp_f64_list_push_front(F64List *list, F64Node *node);
void wapp_f64_list_push_back(F64List *list, F64Node *node);
void wapp_f64_list_insert(F64List *list, F64Node *node, u64 index);
F64Node *wapp_f64_list_pop_front(F64List *list);
F64Node *wapp_f64_list_pop_back(F64List *list);
F64Node *wapp_f64_list_remove(F64List *list, u64 index);
void wapp_f64_list_empty(F64List *list);
F128Node *wapp_f128_list_get(const F128List *list, u64 index);
void wapp_f128_list_push_front(F128List *list, F128Node *node);
void wapp_f128_list_push_back(F128List *list, F128Node *node);
void wapp_f128_list_insert(F128List *list, F128Node *node, u64 index);
F128Node *wapp_f128_list_pop_front(F128List *list);
F128Node *wapp_f128_list_pop_back(F128List *list);
F128Node *wapp_f128_list_remove(F128List *list, u64 index);
void wapp_f128_list_empty(F128List *list);
IptrNode *wapp_iptr_list_get(const IptrList *list, u64 index);
void wapp_iptr_list_push_front(IptrList *list, IptrNode *node);
void wapp_iptr_list_push_back(IptrList *list, IptrNode *node);
void wapp_iptr_list_insert(IptrList *list, IptrNode *node, u64 index);
IptrNode *wapp_iptr_list_pop_front(IptrList *list);
IptrNode *wapp_iptr_list_pop_back(IptrList *list);
IptrNode *wapp_iptr_list_remove(IptrList *list, u64 index);
void wapp_iptr_list_empty(IptrList *list);
UptrNode *wapp_uptr_list_get(const UptrList *list, u64 index);
void wapp_uptr_list_push_front(UptrList *list, UptrNode *node);
void wapp_uptr_list_push_back(UptrList *list, UptrNode *node);
void wapp_uptr_list_insert(UptrList *list, UptrNode *node, u64 index);
UptrNode *wapp_uptr_list_pop_front(UptrList *list);
UptrNode *wapp_uptr_list_pop_back(UptrList *list);
UptrNode *wapp_uptr_list_remove(UptrList *list, u64 index);
void wapp_uptr_list_empty(UptrList *list);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !DBL_LIST_H

View File

@ -0,0 +1,35 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "mem_allocator.h"
#include "../../common/aliases/aliases.h"
#include "../../common/assert/assert.h"
#include <stdlib.h>
void *wapp_mem_allocator_alloc(const Allocator *allocator, u64 size) {
wapp_debug_assert(allocator != NULL && (allocator->alloc) != NULL, "`allocator` and `allocator->alloc` should not be NULL");
return allocator->alloc(size, allocator->obj);
}
void *wapp_mem_allocator_alloc_aligned(const Allocator *allocator, u64 size, u64 alignment) {
wapp_debug_assert(allocator != NULL && (allocator->alloc_aligned) != NULL, "`allocator` and `allocator->alloc_aligned` should not be NULL");
return allocator->alloc_aligned(size, alignment, allocator->obj);
}
void *wapp_mem_allocator_realloc(const Allocator *allocator, void *ptr, u64 old_size, u64 new_size) {
wapp_debug_assert(allocator != NULL && (allocator->realloc) != NULL, "`allocator` and `allocator->realloc` should not be NULL");
return allocator->realloc(ptr, old_size, new_size, allocator->obj);
}
void *wapp_mem_allocator_realloc_aligned(const Allocator *allocator, void *ptr, u64 old_size,
u64 new_size, u64 alignment) {
wapp_debug_assert(allocator != NULL && (allocator->realloc_aligned) != NULL, "`allocator` and `allocator->realloc_aligned` should not be NULL");
return allocator->realloc_aligned(ptr, old_size, new_size, alignment, allocator->obj);
}
void wapp_mem_allocator_free(const Allocator *allocator, void **ptr, u64 size) {
if (!allocator || !(allocator->free)) {
return;
}
allocator->free(ptr, size, allocator->obj);
}

View File

@ -0,0 +1,50 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef MEM_ALLOCATOR_H
#define MEM_ALLOCATOR_H
#include "../../common/aliases/aliases.h"
#include "../../common/platform/platform.h"
#include <string.h>
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
typedef void *(MemAllocFunc)(u64 size, void *alloc_obj);
typedef void *(MemAllocAlignedFunc)(u64 size, u64 alignment, void *alloc_obj);
typedef void *(MemReallocFunc)(void *ptr, u64 old_size, u64 new_size, void *alloc_obj);
typedef void *(MemReallocAlignedFunc)(void *ptr, u64 old_size, u64 new_size, u64 alignment, void *alloc_obj);
typedef void (MemFreeFunc)(void **ptr, u64 size, void *alloc_obj);
typedef struct allocator Allocator;
struct allocator {
void *obj;
MemAllocFunc *alloc;
MemAllocAlignedFunc *alloc_aligned;
MemReallocFunc *realloc;
MemReallocAlignedFunc *realloc_aligned;
MemFreeFunc *free;
};
#ifdef WAPP_PLATFORM_CPP
#define wapp_mem_allocator_invalid(ALLOCATOR) ([&]() { \
Allocator alloc{}; \
return memcmp(ALLOCATOR, &alloc, sizeof(Allocator)) == 0; \
}())
#else
#define wapp_mem_allocator_invalid(ALLOCATOR) (memcmp(ALLOCATOR, &((Allocator){0}), sizeof(Allocator)) == 0)
#endif // !WAPP_PLATFORM_CPP
void *wapp_mem_allocator_alloc(const Allocator *allocator, u64 size);
void *wapp_mem_allocator_alloc_aligned(const Allocator *allocator, u64 size, u64 alignment);
void *wapp_mem_allocator_realloc(const Allocator *allocator, void *ptr, u64 old_size, u64 new_size);
void *wapp_mem_allocator_realloc_aligned(const Allocator *allocator, void *ptr, u64 old_size,
u64 new_size, u64 alignment);
void wapp_mem_allocator_free(const Allocator *allocator, void **ptr, u64 size);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !MEM_ALLOCATOR_H

View File

@ -0,0 +1,446 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "str8.h"
#include "../../../common/aliases/aliases.h"
#include "../../../common/assert/assert.h"
#include "../../mem_allocator/mem_allocator.h"
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#define STR8_BUF_ALLOC_SIZE(CAPACITY) (sizeof(Str8) + sizeof(c8) * CAPACITY)
Str8 *wapp_str8_alloc_buf(const Allocator *allocator, u64 capacity) {
wapp_debug_assert(allocator != NULL, "`allocator` should not be NULL");
Str8 *str = wapp_mem_allocator_alloc(allocator, STR8_BUF_ALLOC_SIZE(capacity));
if (!str) {
goto RETURN_STR8;
}
str->buf = (u8 *)str + sizeof(Str8);
str->size = 0;
str->capacity = capacity;
RETURN_STR8:
return str;
}
Str8 *wapp_str8_alloc_and_fill_buf(const Allocator *allocator, u64 capacity) {
Str8 *out = wapp_str8_alloc_buf(allocator, capacity);
if (out) {
memset(out->buf, 0, capacity);
out->size = capacity;
}
return out;
}
Str8 *wapp_str8_alloc_cstr(const Allocator *allocator, const char *str) {
wapp_debug_assert(allocator != NULL && str != NULL, "`allocator` and `str` should not be NULL");
u64 length = strlen(str);
Str8 *output = wapp_str8_alloc_buf(allocator, length * 2);
if (!output) {
goto RETURN_ALLOC_CSTR;
}
output->size = length;
memcpy(output->buf, str, length);
RETURN_ALLOC_CSTR:
return output;
}
Str8 *wapp_str8_alloc_str8(const Allocator *allocator, Str8RO *str) {
wapp_debug_assert(allocator != NULL && str != NULL, "`allocator` and `str` should not be NULL");
Str8 *output = wapp_str8_alloc_buf(allocator, str->capacity);
if (!output) {
goto RETURN_ALLOC_STR8;
}
output->size = str->size;
memcpy(output->buf, str->buf, str->size);
RETURN_ALLOC_STR8:
return output;
}
Str8 *wapp_str8_alloc_substr(const Allocator *allocator, Str8RO *str, u64 start, u64 end) {
wapp_debug_assert(allocator != NULL && str != NULL, "`allocator` and `str` should not be NULL");
Str8 *output = NULL;
if (start >= str->size || start >= end) {
goto RETURN_ALLOC_SUBSTR;
}
if (end > str->size) {
end = str->size;
}
output = wapp_str8_alloc_buf(allocator, str->capacity);
if (!output) {
goto RETURN_ALLOC_SUBSTR;
}
output->size = end - start;
memcpy(output->buf, str->buf + start, output->size);
RETURN_ALLOC_SUBSTR:
return output;
}
void wapp_str8_dealloc_buf(const Allocator *allocator, Str8 **str) {
wapp_debug_assert(allocator != NULL && str != NULL && (*str) != NULL, "Either `allocator` is NULL or `str` is an invalid double pointer");
wapp_mem_allocator_free(allocator, (void **)str, STR8_BUF_ALLOC_SIZE((*str)->capacity));
}
c8 wapp_str8_get(const Str8 *str, u64 index) {
if (index >= str->size) {
return '\0';
}
return str->buf[index];
}
void wapp_str8_set(Str8 *str, u64 index, c8 c) {
if (index >= str->size) {
return;
}
str->buf[index] = c;
}
void wapp_str8_push_back(Str8 *str, c8 c) {
if (!(str->size < str->capacity)) {
return;
}
u64 index = (str->size)++;
wapp_str8_set(str, index, c);
}
bool wapp_str8_equal(Str8RO *s1, Str8RO *s2) {
if (s1->size != s2->size) {
return false;
}
return wapp_str8_equal_to_count(s1, s2, s1->size);
}
bool wapp_str8_equal_to_count(Str8RO* s1, Str8RO* s2, u64 count) {
if (!s1 || !s2) {
return false;
}
return memcmp(s1->buf, s2->buf, count) == 0;
}
Str8 wapp_str8_slice(Str8RO *str, u64 start, u64 end) {
if (start >= str->size || start >= end) {
start = str->size;
end = str->size;
}
if (end > str->size) {
end = str->size;
}
return (Str8RO){
.capacity = end - start,
.size = end - start,
.buf = str->buf + start,
};
}
Str8 *wapp_str8_alloc_concat(const Allocator *allocator, Str8 *dst, Str8RO *src) {
wapp_debug_assert(allocator != NULL && dst != NULL && src != NULL, "`allocator`, `dst` and `src` should not be NULL");
Str8 *output = NULL;
u64 remaining = dst->capacity - dst->size;
if (src->size <= remaining) {
output = dst;
goto COPY_STRING_STR8_CONCAT;
}
u64 capacity = dst->capacity + src->size;
output = wapp_str8_alloc_buf(allocator, capacity);
if (!output) {
goto RETURN_STR8_CONCAT;
}
wapp_str8_concat_capped(output, dst);
COPY_STRING_STR8_CONCAT:
wapp_str8_concat_capped(output, src);
RETURN_STR8_CONCAT:
return output;
}
void wapp_str8_concat_capped(Str8 *dst, Str8RO *src) {
wapp_debug_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL");
u64 remaining = dst->capacity - dst->size;
u64 to_copy = remaining < src->size ? remaining : src->size;
memcpy(dst->buf + dst->size, src->buf, to_copy);
dst->size += to_copy;
}
void wapp_str8_copy_cstr_capped(Str8 *dst, const char *src) {
wapp_debug_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL");
u64 length = strlen(src);
u64 to_copy = length <= dst->capacity ? length : dst->capacity;
memset(dst->buf, 0, dst->size);
memcpy(dst->buf, src, to_copy);
dst->size = to_copy;
}
void wapp_str8_copy_str8_capped(Str8 *dst, Str8RO *src) {
wapp_debug_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL");
u64 to_copy = src->size <= dst->capacity ? src->size : dst->capacity;
memset(dst->buf, 0, dst->size);
memcpy(dst->buf, src->buf, to_copy);
dst->size = to_copy;
}
void wapp_str8_copy_to_cstr(char *dst, Str8RO *src, u64 dst_capacity) {
wapp_debug_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL");
u64 to_copy = src->size < dst_capacity ? src->size : dst_capacity - 1;
memset(dst, 0, dst_capacity);
memcpy(dst, src->buf, to_copy);
}
void wapp_str8_format(Str8 *dst, const char *format, ...) {
wapp_debug_assert(dst != NULL && format != NULL, "`dst` and `format` should not be NULL");
va_list args1;
va_list args2;
va_start(args1, format);
va_copy(args2, args1);
u64 total_size = vsnprintf(NULL, 0, format, args1);
dst->size = total_size <= dst->capacity ? total_size : dst->capacity;
vsnprintf((char *)(dst->buf), dst->capacity, format, args2);
va_end(args1);
va_end(args2);
}
i64 wapp_str8_find(Str8RO *str, Str8RO substr) {
if (!str || substr.size > str->size) {
return -1;
}
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
u64 char_index = 0;
bool running = char_index < str->size;
while (running) {
const c8 *sub = str->buf + char_index;
if (memcmp(sub, substr.buf, substr.size) == 0) {
return char_index;
}
++char_index;
running = char_index < str->size;
}
return -1;
}
i64 wapp_str8_rfind(Str8RO *str, Str8RO substr) {
if (!str || substr.size > str->size) {
return -1;
}
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
i64 char_index = str->size - substr.size;
bool running = char_index >= 0;
while (running) {
const c8 *sub = str->buf + char_index;
if (memcmp(sub, substr.buf, substr.size) == 0) {
return char_index;
}
--char_index;
running = char_index >= 0;
}
return -1;
}
Str8List *wapp_str8_split_with_max(const Allocator *allocator, Str8RO *str, Str8RO *delimiter, i64 max_splits) {
wapp_debug_assert(allocator != NULL && str != NULL && delimiter != NULL, "`allocator`, `str` and `delimiter` should not be NULL");
Str8List *output = wapp_mem_allocator_alloc(allocator, sizeof(Str8List));
if (delimiter->size > str->size) {
Str8 *full = wapp_str8_alloc_str8(allocator, str);
Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node));
if (node) {
node->item = full;
wapp_str8_list_push_back(output, node);
}
goto RETURN_STR8_SPLIT;
}
i64 start = 0;
i64 end = 0;
i64 splits = 0;
Str8 *rest = wapp_str8_alloc_str8(allocator, str);
Str8 *before_str;
while ((end = wapp_str8_find(rest, *delimiter)) != -1) {
if (max_splits > 0 && splits >= max_splits) {
break;
}
before_str = wapp_str8_alloc_substr(allocator, str, start, start + end);
Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node));
if (node && before_str) {
node->item = before_str;
wapp_str8_list_push_back(output, node);
}
wapp_mem_allocator_free(allocator, (void **)&rest, sizeof(Str8));
rest = wapp_str8_alloc_substr(allocator, str, start + end + delimiter->size, str->size);
start += end + delimiter->size;
++splits;
}
// Ensure the last part of the string after the delimiter is added to the list
rest = wapp_str8_alloc_substr(allocator, str, start, str->size);
Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node));
if (node && rest) {
node->item = rest;
wapp_str8_list_push_back(output, node);
}
RETURN_STR8_SPLIT:
return output;
}
Str8List *wapp_str8_rsplit_with_max(const Allocator *allocator, Str8RO *str, Str8RO *delimiter, i64 max_splits) {
wapp_debug_assert(allocator != NULL && str != NULL && delimiter != NULL, "`allocator`, `str` and `delimiter` should not be NULL");
Str8List *output = wapp_mem_allocator_alloc(allocator, sizeof(Str8List));
if (delimiter->size > str->size) {
Str8 *full = wapp_str8_alloc_str8(allocator, str);
Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node));
if (node && full) {
node->item = full;
wapp_str8_list_push_back(output, node);
}
goto RETURN_STR8_SPLIT;
}
i64 end = 0;
i64 splits = 0;
Str8 *rest = wapp_str8_alloc_str8(allocator, str);
Str8 *after_str;
while ((end = wapp_str8_rfind(rest, *delimiter)) != -1) {
if (max_splits > 0 && splits >= max_splits) {
break;
}
after_str = wapp_str8_alloc_substr(allocator, rest, end + delimiter->size, str->size);
Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node));
if (node) {
node->item = after_str;
wapp_str8_list_push_front(output, node);
}
wapp_mem_allocator_free(allocator, (void **)&rest, sizeof(Str8));
rest = wapp_str8_alloc_substr(allocator, rest, 0, end);
++splits;
}
rest = wapp_str8_alloc_substr(allocator, str, 0, rest->size);
Str8Node *node = wapp_mem_allocator_alloc(allocator, sizeof(Str8Node));
if (node && rest) {
node->item = rest;
wapp_str8_list_push_front(output, node);
}
RETURN_STR8_SPLIT:
return output;
}
Str8 *wapp_str8_join(const Allocator *allocator, const Str8List *list, Str8RO *delimiter) {
wapp_debug_assert(allocator != NULL && list != NULL && delimiter != NULL, "`allocator`, `list` and `delimiter` should not be NULL");
u64 capacity = wapp_str8_list_total_size(list) + (delimiter->size * (list->node_count - 1));
Str8 *output = wapp_str8_alloc_buf(allocator, capacity * 2);
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
Str8Node *node;
u64 node_index = 0;
bool running = node_index < list->node_count;
while (running) {
node = wapp_str8_list_get(list, node_index);
if (!node) {
break;
}
wapp_str8_concat_capped(output, node->item);
// NOTE (Abdelrahman): Comparison extracted to variable to silence
// MSVC Spectre mitigation warnings
bool not_last = node_index + 1 < list->node_count;
if (not_last) {
wapp_str8_concat_capped(output, delimiter);
}
++node_index;
running = node_index < list->node_count;
}
return output;
}
u64 wapp_str8_list_total_size(const Str8List *list) {
if (!list) {
return 0;
}
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
Str8Node* node;
u64 node_index = 0;
u64 output = 0;
bool running = node_index < list->node_count;
while (running) {
node = wapp_str8_list_get(list, node_index);
if (!node) {
break;
}
output += node->item->size;
++node_index;
running = node_index < list->node_count;
}
return output;
}

View File

@ -0,0 +1,138 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef STR8_H
#define STR8_H
#include "../../../common/aliases/aliases.h"
#include "../../../common/assert/assert.h"
#include "../../../common/platform/platform.h"
#include "../../../primitives/dbl_list/dbl_list.h"
#include "../../mem_allocator/mem_allocator.h"
#include <string.h>
#include <stdbool.h>
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
typedef struct str8 Str8;
struct str8 {
u64 capacity;
u64 size;
c8 *buf;
};
typedef const Str8 Str8RO;
/**
* Utilities to be used with printf functions
*/
#define WAPP_STR8_SPEC "%.*s"
#define wapp_str8_varg(STRING) (int)((STRING).size), (STRING).buf
/**
* Str8 stack buffers
*/
#ifdef WAPP_PLATFORM_CPP
// Uses a lambda to achieve the same behaviour achieved by the C macro
#define wapp_str8_buf(CAPACITY) ([&](){ \
persistent c8 buf[CAPACITY] = {}; \
memset(buf, 0, CAPACITY); \
return Str8{CAPACITY, 0, buf}; \
}())
// Uses a lambda to achieve the same behaviour achieved by the C macro
#define wapp_str8_lit(STRING) ([&]() { \
persistent c8 buf[sizeof(STRING) * 2] = {}; \
memcpy(buf, STRING, sizeof(STRING)); \
return Str8{(sizeof(STRING) - 1) * 2, sizeof(STRING) - 1, buf}; \
}())
#define wapp_str8_lit_ro(STRING) Str8RO{sizeof(STRING) - 1, sizeof(STRING) - 1, (c8 *)STRING}
#define wapp_str8_lit_ro_initialiser_list(STRING) {sizeof(STRING) - 1, sizeof(STRING) - 1, (c8 *)STRING}
#else
#define wapp_str8_buf(CAPACITY) ((Str8){.capacity = CAPACITY, .size = 0, .buf = (c8[CAPACITY]){0}})
// Utilises the fact that memcpy returns pointer to dest buffer and that getting
// address of compound literals is valid in C to create a string on the stack
#define wapp_str8_lit(STRING) ((Str8){.capacity = (sizeof(STRING) - 1) * 2, \
.size = sizeof(STRING) - 1, \
.buf = memcpy(&((c8 [sizeof(STRING) * 2]){0}), STRING, sizeof(STRING))})
#define wapp_str8_lit_ro(STRING) ((Str8RO){.capacity = sizeof(STRING) - 1, \
.size = sizeof(STRING) - 1, \
.buf = (c8 *)STRING})
// To be used only when initialising a static storage variable in compilers that don't support
// initialisers with the syntax of wapp_str8_lit_ro (e.g. gcc). Should only be used when necessary
// and only be assigned to a Str8RO variable to avoid any attempt at modifying the string
#define wapp_str8_lit_ro_initialiser_list(STRING) {.capacity = sizeof(STRING) - 1, \
.size = sizeof(STRING) - 1, \
.buf = (c8 *)STRING}
#endif // !WAPP_PLATFORM_CPP
/**
* Str8 allocated buffers
*/
Str8 *wapp_str8_alloc_buf(const Allocator *allocator, u64 capacity);
Str8 *wapp_str8_alloc_and_fill_buf(const Allocator *allocator, u64 capacity);
Str8 *wapp_str8_alloc_cstr(const Allocator *allocator, const char *str);
Str8 *wapp_str8_alloc_str8(const Allocator *allocator, Str8RO *str);
Str8 *wapp_str8_alloc_substr(const Allocator *allocator, Str8RO *str, u64 start, u64 end);
Str8 *wapp_str8_alloc_concat(const Allocator *allocator, Str8 *dst, Str8RO *src);
// Only needed for allocators like malloc where each allocation has to be freed on its own.
// No need to use it for allocators like Arena.
void wapp_str8_dealloc_buf(const Allocator *allocator, Str8 **str);
/**
* Str8 utilities
*/
c8 wapp_str8_get(Str8RO *str, u64 index);
void wapp_str8_set(Str8 *str, u64 index, c8 c);
void wapp_str8_push_back(Str8 *str, c8 c);
bool wapp_str8_equal(Str8RO *s1, Str8RO *s2);
bool wapp_str8_equal_to_count(Str8RO* s1, Str8RO* s2, u64 count);
Str8 wapp_str8_slice(Str8RO *str, u64 start, u64 end);
void wapp_str8_concat_capped(Str8 *dst, Str8RO *src);
void wapp_str8_copy_cstr_capped(Str8 *dst, const char *src);
void wapp_str8_copy_str8_capped(Str8 *dst, Str8RO *src);
void wapp_str8_copy_to_cstr(char *dst, Str8RO *src, u64 dst_capacity);
void wapp_str8_format(Str8 *dst, const char *format, ...);
/**
* Str8 find functions
*/
i64 wapp_str8_find(Str8RO *str, Str8RO substr);
i64 wapp_str8_rfind(Str8RO *str, Str8RO substr);
/**
* Str8 split and join
*/
#define wapp_str8_split(ALLOCATOR, STR, DELIMITER) wapp_str8_split_with_max(ALLOCATOR, STR, DELIMITER, -1)
#define wapp_str8_rsplit(ALLOCATOR, STR, DELIMITER) wapp_str8_rsplit_with_max(ALLOCATOR, STR, DELIMITER, -1)
Str8List *wapp_str8_split_with_max(const Allocator *allocator, Str8RO *str, Str8RO *delimiter, i64 max_splits);
Str8List *wapp_str8_rsplit_with_max(const Allocator *allocator, Str8RO *str, Str8RO *delimiter, i64 max_splits);
Str8 *wapp_str8_join(const Allocator *allocator, const Str8List *list, Str8RO *delimiter);
/**
* Str8 list utilities
*/
#ifdef WAPP_PLATFORM_CPP
#define wapp_str8_node_from_cstr(STRING) wapp_str8_list_node([&]() { \
persistent Str8 str = wapp_str8_lit(STRING); \
return &str; \
}())
#define wapp_str8_node_from_str8(STRING) wapp_str8_list_node([&]() { \
persistent Str8 str = STRING; \
return &str; \
}())
#else
#define wapp_str8_node_from_cstr(STRING) wapp_str8_list_node(&wapp_str8_lit(STRING))
#define wapp_str8_node_from_str8(STRING) wapp_str8_list_node(&(STRING))
#endif // !WAPP_PLATFORM_CPP
u64 wapp_str8_list_total_size(const Str8List *list);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !STR8_H

View File

@ -0,0 +1,12 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_PRIMITIVES_C
#define WAPP_PRIMITIVES_C
#include "wapp_primitives.h"
#include "array/array.c"
#include "dbl_list/dbl_list.c"
#include "mem_allocator/mem_allocator.c"
#include "strings/str8/str8.c"
#endif // !WAPP_PRIMITIVES_C

View File

@ -0,0 +1,12 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_PRIMITIVES_H
#define WAPP_PRIMITIVES_H
#include "dbl_list/dbl_list.h"
#include "array/array.h"
#include "mem_allocator/mem_allocator.h"
#include "strings/str8/str8.h"
#include "../common/wapp_common.h"
#endif // !WAPP_PRIMITIVES_H

8
wapp/prng/wapp_prng.c Normal file
View File

@ -0,0 +1,8 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_PRNG_C
#define WAPP_PRNG_C
#include "xorshift/xorshift.c"
#endif // !WAPP_PRNG_C

9
wapp/prng/wapp_prng.h Normal file
View File

@ -0,0 +1,9 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_PRNG_H
#define WAPP_PRNG_H
#include "xorshift/xorshift.h"
#include "../common/wapp_common.h"
#endif // !WAPP_PRNG_H

View File

@ -0,0 +1,136 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "xorshift.h"
#include "../../common/aliases/aliases.h"
#include "../../common/assert/assert.h"
#include "../../common/platform/platform.h"
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
typedef struct split_mix_64_state SplitMix64State;
struct split_mix_64_state {
u64 seed;
};
internal u64 rol64(u64 x, u64 bits);
internal u64 split_mix_64(SplitMix64State *state);
internal void seed_os_generator(void);
internal u64 generate_random_number(void);
XOR256State wapp_prng_xorshift_init_state(void) {
persistent bool seeded = false;
if (!seeded) {
seeded = true;
seed_os_generator();
}
SplitMix64State sm64 = {.seed = generate_random_number()};
return (XOR256State){
.x = split_mix_64(&sm64),
.y = split_mix_64(&sm64),
.z = split_mix_64(&sm64),
.w = split_mix_64(&sm64),
};
}
u64 wapp_prng_xorshift_256(XOR256State *state) {
u64 t = state->x ^ (state->x << 11);
state->x = state->y;
state->y = state->z;
state->z = state->w;
state->w = (state->w ^ (state->w >> 19)) ^ (t ^ (t >> 8));
return state->w;
}
u64 wapp_prng_xorshift_256ss(XOR256State *state) {
const u64 result = rol64(state->z * 5, 7) * 9;
const u64 t = state->z << 17;
state->y ^= state->w;
state->x ^= state->z;
state->z ^= state->y;
state->w ^= state->x;
state->y ^= t;
state->x = rol64(state->x, 45);
return result;
}
u64 wapp_prng_xorshift_256p(XOR256State *state) {
const u64 result = state->w + state->x;
const u64 t = state->z << 17;
state->y ^= state->w;
state->x ^= state->z;
state->z ^= state->y;
state->w ^= state->x;
state->y ^= t;
state->x = rol64(state->x, 45);
return result;
}
internal u64 rol64(u64 x, u64 bits) {
return (x << bits) | (x >> (64 - bits));
}
internal u64 split_mix_64(SplitMix64State *state) {
state->seed += 0x9E3779B97f4A7C15;
u64 result = state->seed;
result = (result ^ (result >> 30)) * 0xBF58476D1CE4E5B9;
result = (result ^ (result >> 27)) * 0x94D049BB133111EB;
return result ^ (result >> 31);
}
#if defined(WAPP_PLATFORM_C) && WAPP_PLATFORM_C_VERSION >= WAPP_PLATFORM_C11_VERSION
#ifdef WAPP_PLATFORM_POSIX
internal void seed_os_generator(void) {
struct timespec ts = {0};
int result = clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
wapp_runtime_assert(result == 0, "Invalid seed value");
srand48(ts.tv_nsec);
}
internal u64 generate_random_number(void) {
return lrand48();
}
#else
internal void seed_os_generator(void) {
struct timespec ts = {0};
int result = timespec_get(&ts, TIME_UTC);
wapp_runtime_assert(result != 0, "Invalid seed value");
srand(ts.tv_nsec);
}
internal u64 generate_random_number(void) {
i32 n1 = rand();
i32 n2 = rand();
return (((u64)n1) << 32 | (u64)n2);
}
#endif // !WAPP_PLATFORM_POSIX
#else
internal void seed_os_generator(void) {
time_t result = time(NULL);
wapp_runtime_assert(result != (time_t)(-1), "Invalid seed value");
srand(result);
}
internal u64 generate_random_number(void) {
i32 n1 = rand();
i32 n2 = rand();
return (((u64)n1) << 32 | (u64)n2);
}
#endif // !WAPP_PLATFORM_C

View File

@ -0,0 +1,30 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef XORSHIFT_H
#define XORSHIFT_H
#include "../../common/aliases/aliases.h"
#include "../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
typedef struct xor_256_state XOR256State;
struct xor_256_state {
u64 x;
u64 y;
u64 z;
u64 w;
};
XOR256State wapp_prng_xorshift_init_state(void);
u64 wapp_prng_xorshift_256(XOR256State *state);
u64 wapp_prng_xorshift_256ss(XOR256State *state);
u64 wapp_prng_xorshift_256p(XOR256State *state);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !XORSHIFT_H

View File

@ -0,0 +1,55 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "tester.h"
#include "../../common/aliases/aliases.h"
#include "../../core/os/shell/termcolour/termcolour.h"
#include "../../primitives/strings/str8/str8.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
internal void handle_test_result(TestFuncResult result);
void run_tests(TestFunc *func1, ...) {
printf("\n");
handle_test_result(func1());
va_list args;
va_start(args, func1);
TestFunc *func = va_arg(args, TestFunc *);
while (func) {
TestFuncResult result = func();
handle_test_result(result);
func = va_arg(args, TestFunc *);
}
va_end(args);
printf("\n");
}
internal void handle_test_result(TestFuncResult result) {
TerminalColour colour;
Str8 result_text = wapp_str8_buf(64);
if (result.passed) {
colour = WAPP_TERM_COLOUR_FG_BR_GREEN;
wapp_str8_copy_cstr_capped(&result_text, "PASSED");
} else {
colour = WAPP_TERM_COLOUR_FG_BR_RED;
wapp_str8_copy_cstr_capped(&result_text, "FAILED");
}
printf("[");
wapp_shell_termcolour_print_text(&result_text, colour);
wapp_shell_termcolour_clear_colour();
printf("] " WAPP_STR8_SPEC "\n", wapp_str8_varg(result.name));
if (!result.passed) {
exit(EXIT_FAILURE);
}
}

View File

@ -0,0 +1,41 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef TESTER_H
#define TESTER_H
#include "../../common/misc/misc_utils.h"
#include "../../common/platform/platform.h"
#include "../../primitives/strings/str8/str8.h"
#include <stdbool.h>
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_CPP
#define wapp_tester_result(PASSED) (TestFuncResult{wapp_str8_lit_ro(__func__), PASSED})
#else
#define wapp_tester_result(PASSED) ((TestFuncResult){.name = wapp_str8_lit_ro(__func__), .passed = PASSED})
#endif // !WAPP_PLATFORM_CPP
#define wapp_tester_run_tests(...) run_tests(__VA_ARGS__, NULL)
typedef struct test_func_result TestFuncResult;
struct test_func_result {
Str8RO name;
bool passed;
#ifdef WAPP_PLATFORM_WINDOWS
wapp_misc_utils_padding_size(sizeof(Str8RO) + sizeof(bool));
#endif // WAPP_PLATFORM_WINDOWS
};
typedef TestFuncResult(TestFunc)(void);
void run_tests(TestFunc *func1, ...);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !TESTER_H

View File

@ -0,0 +1,10 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_TESTING_C
#define WAPP_TESTING_C
#include "wapp_testing.h"
#include "tester/tester.c"
#include "../core/wapp_core.c"
#endif // !WAPP_TESTING_C

View File

@ -0,0 +1,10 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_TESTING_H
#define WAPP_TESTING_H
#include "tester/tester.h"
#include "../common/wapp_common.h"
#include "../core/wapp_core.h"
#endif // !WAPP_TESTING_H

59
wapp/uuid/uuid.c Normal file
View File

@ -0,0 +1,59 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "uuid.h"
#include "../common/aliases/aliases.h"
#include "../common/assert/assert.h"
#include "../primitives/strings/str8/str8.h"
#include "../prng/xorshift/xorshift.h"
#include <stdbool.h>
#include <inttypes.h>
#define UUID_STR_FORMAT ("%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.12" PRIx64)
typedef struct uuid4 UUID4;
struct uuid4 {
u64 high;
u64 low;
};
internal UUID4 generate_uuid4(void);
internal void uuid4_to_uuid(const UUID4* uuid4, UUID *uuid);
UUID *wapp_uuid_init_uuid4(UUID *uuid) {
wapp_debug_assert(uuid != NULL, "`uuid` should not be NULL");
UUID4 uuid4 = generate_uuid4();
uuid4_to_uuid(&uuid4, uuid);
return uuid;
}
internal UUID4 generate_uuid4(void) {
persistent XOR256State state = {0};
persistent bool initialised = false;
if (!initialised) {
initialised = true;
state = wapp_prng_xorshift_init_state();
}
UUID4 uuid = (UUID4){
.high = wapp_prng_xorshift_256(&state),
.low = wapp_prng_xorshift_256(&state),
};
uuid.high = (uuid.high & 0xffffffffffff0fff) | 0x0000000000004000;
uuid.low = (uuid.low & 0x3fffffffffffffff) | 0x8000000000000000;
return uuid;
}
internal void uuid4_to_uuid(const UUID4* uuid4, UUID *uuid) {
u64 grp1 = uuid4->high >> 32;
u64 grp2 = (uuid4->high << 32) >> 48;
u64 grp3 = (uuid4->high << 48) >> 48;
u64 grp4 = uuid4->low >> 48;
u64 grp5 = (uuid4->low << 16) >> 16;
wapp_str8_format(&(uuid->uuid), UUID_STR_FORMAT, grp1, grp2, grp3, grp4, grp5);
}

37
wapp/uuid/uuid.h Normal file
View File

@ -0,0 +1,37 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef UUID_H
#define UUID_H
#include "../common/aliases/aliases.h"
#include "../common/platform/platform.h"
#include "../primitives/strings/str8/str8.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#define UUID_BUF_LENGTH 48
#define WAPP_UUID_SPEC WAPP_STR8_SPEC
#define wapp_uuid_varg(UUID) wapp_str8_varg((UUID).uuid)
typedef struct uuid UUID;
struct uuid {
Str8 uuid;
};
#define wapp_uuid_gen_uuid4() *(wapp_uuid_init_uuid4(&wapp_uuid_create()))
/* Low level UUID API */
#define wapp_uuid_create() ((UUID){.uuid = wapp_str8_buf(UUID_BUF_LENGTH)})
// Just returns the same pointer that was passed in with the UUID initialised.
// Fails when passed a NULL pointer.
UUID *wapp_uuid_init_uuid4(UUID *uuid);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !UUID_H

10
wapp/uuid/wapp_uuid.c Normal file
View File

@ -0,0 +1,10 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_UUID_C
#define WAPP_UUID_C
#include "uuid.c"
#include "../primitives/wapp_primitives.c"
#include "../prng/wapp_prng.c"
#endif // !WAPP_UUID_C

11
wapp/uuid/wapp_uuid.h Normal file
View File

@ -0,0 +1,11 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_UUID_H
#define WAPP_UUID_H
#include "uuid.h"
#include "../common/wapp_common.h"
#include "../primitives/wapp_primitives.h"
#include "../prng/wapp_prng.h"
#endif // !WAPP_UUID_H

13
wapp/wapp.c Normal file
View File

@ -0,0 +1,13 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_C
#define WAPP_C
#include "wapp.h"
#include "primitives/wapp_primitives.c"
#include "core/wapp_core.c"
#include "prng/wapp_prng.c"
#include "uuid/uuid.c"
#include "testing/wapp_testing.c"
#endif // !WAPP_C

13
wapp/wapp.h Normal file
View File

@ -0,0 +1,13 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef WAPP_H
#define WAPP_H
#include "common/wapp_common.h"
#include "primitives/wapp_primitives.h"
#include "core/wapp_core.h"
#include "prng/wapp_prng.h"
#include "uuid/wapp_uuid.h"
#include "testing/wapp_testing.h"
#endif // !WAPP_H