49 Commits

Author SHA1 Message Date
Abdelrahman Said
3d3452f523 Update queue implementation to use ring buffer 2026-01-24 20:46:05 +00:00
Abdelrahman Said
8e41b627bc Add function to create array from preallocated buffer 2026-01-24 20:45:52 +00:00
Abdelrahman Said
7a54c28c0f Update array allocation functions 2026-01-24 12:17:15 +00:00
Abdelrahman Said
bd659e64fc Ensure array count is set correctly when allocating 2026-01-22 06:09:43 +00:00
Abdelrahman Said
21ac756fad Pass init flags to allocating array utilities 2026-01-19 06:09:36 +00:00
Abdelrahman Said
243f04c0ca Handle lseek64 not existing on macOS 2026-01-19 06:00:09 +00:00
4cc8cb3d25 Fix MSVC errors 2026-01-11 23:48:35 +00:00
a9f5b9c3c6 Add queue implementation 2026-01-11 23:46:23 +00:00
9af9cedd51 Add pointer offset utility 2026-01-11 23:46:12 +00:00
1e536cc3ba Rename array alloc size utility 2026-01-11 21:58:49 +00:00
e6f31e4f7b Update dbl list utilities 2026-01-11 21:46:00 +00:00
6cd3c6f596 Add utility to get node item 2026-01-11 21:31:55 +00:00
5a504c6791 Add extra utilities for dbl list 2026-01-11 21:26:17 +00:00
a4492cf8e8 Switch array fill to flags 2026-01-11 20:17:09 +00:00
ce76ac1e7c Add utility to calculate allocation size for array 2026-01-11 19:44:22 +00:00
cff418b9e9 Simplify dbl list API (#11)
Reviewed-on: #11
Co-authored-by: Abdelrahman <said.abdelrahman89@gmail.com>
Co-committed-by: Abdelrahman <said.abdelrahman89@gmail.com>
2026-01-11 18:22:54 +00:00
b88cb71aa8 Update array and dbl list macros 2026-01-05 03:57:50 +00:00
8efcf14462 Switch numerical aliases to typedefs 2026-01-04 23:10:58 +00:00
f383fbb43e Reformat 2026-01-04 16:04:09 +00:00
24069529c3 Add temp arena support 2026-01-04 01:21:42 +00:00
d2b4ec2052 Rename dbl list labels 2026-01-03 20:20:40 +00:00
0a761eef05 Reformat 2026-01-03 19:53:43 +00:00
821406315e Reformat 2026-01-03 19:51:26 +00:00
8adbc1f841 Reformat 2026-01-03 19:17:10 +00:00
1f3df20b7d Reformat 2026-01-03 19:13:42 +00:00
458046a5d0 Reformat 2026-01-03 18:51:30 +00:00
6d4a72aff9 Fix MSVC errors 2026-01-03 18:45:54 +00:00
326265722e Add support for initialising arena with backing buffer 2026-01-03 18:36:30 +00:00
83b879a180 Always reserve padding for structs that need it 2026-01-03 17:04:36 +00:00
b372447a46 Implement Windows file IO 2026-01-03 03:15:25 +00:00
fac9cb57eb Update windows include 2026-01-03 03:15:03 +00:00
abad2fa02a Add padding to stack array 2026-01-03 03:14:53 +00:00
576699996f Update POSIX file IO 2026-01-03 03:13:42 +00:00
c2ca99cac4 Implement POSIX file IO 2026-01-02 22:57:12 +00:00
a07f05d1a3 Use 64 bit offsets for file seeking 2026-01-02 22:56:26 +00:00
ebf16c6ba3 Move is_power_of_two to misc_utils 2026-01-02 19:19:25 +00:00
91138f9239 Reformat 2026-01-02 19:03:19 +00:00
ae8cb2e473 Add function to rename file 2026-01-02 19:02:17 +00:00
f5c2ed89a4 Add tests for file IO API 2026-01-02 18:56:19 +00:00
989a5f60c4 Update file IO API 2026-01-02 18:56:09 +00:00
659a3e457c Reformat 2026-01-02 17:17:25 +00:00
c2a156e256 Remove array structs (#10)
Reviewed-on: #10
2026-01-02 16:50:52 +00:00
f3ee1ee468 Unify struct names and tags 2026-01-02 14:00:00 +00:00
7be1b42107 Reformat tests 2026-01-02 01:12:01 +00:00
41cac2ef7f Reformat os 2026-01-02 00:49:21 +00:00
24716505be Reformat prng 2026-01-02 00:38:44 +00:00
7e21961943 Reformat uuid 2026-01-02 00:36:05 +00:00
6f27d5ea91 Reformat common 2026-01-02 00:30:55 +00:00
54691a8ede Reformat base 2026-01-02 00:29:24 +00:00
72 changed files with 3250 additions and 1761 deletions

View File

@@ -10,7 +10,7 @@ INSTALL_PREFIX = dist
RUNTIME_ASSERT = true RUNTIME_ASSERT = true
# Internal variables # Internal variables
override CFLAGS = -Wall -Wextra -Werror -pedantic -Isrc override CFLAGS = -Wall -Wextra -Werror -pedantic -Isrc -D_LARGEFILE64_SOURCE
override LIBFLAGS = -fPIC override LIBFLAGS = -fPIC
override CSTD := -std=gnu11 override CSTD := -std=gnu11
override CXXSTD := -std=gnu++11 override CXXSTD := -std=gnu++11
@@ -147,7 +147,7 @@ uuid: install
clean: clean:
@rm -rf "$(BUILD_DIR)" @rm -rf "$(BUILD_DIR)"
@rm -rf "$(INCLUDE_INSTALL)" @rm -rf "$(INCLUDE_INSTALL)"
@rm "$(LIB_INSTALL)/$(LIB_STATIC_NAME)" @rm -f "$(LIB_INSTALL)/$(LIB_STATIC_NAME)"
builddir: builddir:
@mkdir -p "$(BUILD_DIR)" @mkdir -p "$(BUILD_DIR)"

View File

@@ -52,9 +52,6 @@ mkdir -p $ObjDir > $null
mkdir -p $OutDir > $null mkdir -p $OutDir > $null
mkdir -p $TestsDir > $null mkdir -p $TestsDir > $null
# Run code generation
Invoke-Expression "python -m codegen"
# Build and run C tests # Build and run C tests
Invoke-Expression "$Compiler $GeneralFlags $CStd $IncludeDirs $TestIncludeDirs $SrcFiles $TestCSrcFiles $TestCOutputFlags" -ErrorAction Stop Invoke-Expression "$Compiler $GeneralFlags $CStd $IncludeDirs $TestIncludeDirs $SrcFiles $TestCSrcFiles $TestCOutputFlags" -ErrorAction Stop
Invoke-Expression "$TestsDir/$TestCOutputBasename.exe" Invoke-Expression "$TestsDir/$TestCOutputBasename.exe"

View File

@@ -7,66 +7,115 @@
#include "../../common/aliases/aliases.h" #include "../../common/aliases/aliases.h"
#include <stddef.h> #include <stddef.h>
#define _offset_pointer(PTR, OFFSET) ((void *)((uptr)(PTR) + (OFFSET))) #define _array_header(ARRAY) (ArrayHeader *)(wapp_pointer_offset(ARRAY, (i64)sizeof(ArrayHeader) * -1))
wapp_persist inline void _array_validate(const GenericArray *array, u64 item_size); wapp_persist inline void _array_validate(const GenericArray array, u64 item_size);
void *_array_get(GenericArray *array, u64 index, u64 item_size) { u64 _array_count(GenericArray array) {
wapp_runtime_assert(array != NULL, "`array` should not be NULL"); wapp_debug_assert(array != NULL, "`array` should not be NULL");
_array_validate(array, item_size);
wapp_runtime_assert(index < array->count, "`index` is out of bounds");
return _offset_pointer(array->items, array->item_size * index); ArrayHeader *header = _array_header(array);
wapp_runtime_assert(WAPP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array");
return header->count;
} }
void _array_set(GenericArray *array, u64 index, void *value, u64 item_size) { u64 _array_capacity(GenericArray array) {
wapp_debug_assert(array != NULL, "`array` should not be NULL");
ArrayHeader *header = _array_header(array);
wapp_runtime_assert(WAPP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array");
return header->capacity;
}
u64 _array_item_size(GenericArray array) {
wapp_debug_assert(array != NULL, "`array` should not be NULL");
ArrayHeader *header = _array_header(array);
wapp_runtime_assert(WAPP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array");
return header->item_size;
}
void _array_set_count(GenericArray array, u64 count) {
wapp_debug_assert(array != NULL, "`array` should not be NULL");
ArrayHeader *header = _array_header(array);
wapp_runtime_assert(WAPP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array");
header->count = count;
}
void *_array_get(GenericArray array, u64 index, u64 item_size) {
wapp_runtime_assert(array != NULL, "`array` should not be NULL");
_array_validate(array, item_size);
ArrayHeader *header = _array_header(array);
wapp_runtime_assert(index < header->count, "`index` is out of bounds");
return wapp_pointer_offset(array, header->item_size * index);
}
void _array_set(GenericArray array, u64 index, void *value, u64 item_size) {
void *item = _array_get(array, index, item_size); void *item = _array_get(array, index, item_size);
memcpy(item, value, array->item_size);
ArrayHeader *header = _array_header(array);
memcpy(item, value, header->item_size);
} }
void _array_append_capped(GenericArray *array, void *value, u64 item_size) { void _array_append_capped(GenericArray array, void *value, u64 item_size) {
wapp_runtime_assert(array != NULL, "`array` should not be NULL"); wapp_runtime_assert(array != NULL, "`array` should not be NULL");
_array_validate(array, item_size); _array_validate(array, item_size);
if (array->count >= array->capacity) { return; } ArrayHeader *header = _array_header(array);
if (header->count >= header->capacity) { return; }
u64 index = (array->count)++; u64 index = (header->count)++;
_array_set(array, index, value, item_size); _array_set(array, index, value, item_size);
} }
void _array_extend_capped(GenericArray *dst, const GenericArray *src, u64 item_size) { void _array_extend_capped(GenericArray dst, const GenericArray src, u64 item_size) {
wapp_runtime_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL"); wapp_runtime_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL");
_array_validate(dst, item_size); _array_validate(dst, item_size);
_array_validate(src, item_size); _array_validate(src, item_size);
u64 remaining_capacity = dst->capacity - dst->count; ArrayHeader *src_header = _array_header(src);
ArrayHeader *dst_header = _array_header(dst);
u64 remaining_capacity = dst_header->capacity - dst_header->count;
u64 copy_count = src->count < remaining_capacity ? src->count : remaining_capacity; u64 copy_count = src_header->count < remaining_capacity ? src_header->count : remaining_capacity;
void *dst_ptr = _offset_pointer(dst->items, dst->count * dst->item_size); void *dst_ptr = wapp_pointer_offset(dst, dst_header->count * dst_header->item_size);
memcpy(dst_ptr, src->items, copy_count * src->item_size); memcpy(dst_ptr, src, copy_count * src_header->item_size);
dst->count += copy_count; dst_header->count += copy_count;
} }
void _array_copy_capped(GenericArray *dst, const GenericArray *src, u64 item_size) { void _array_copy_capped(GenericArray dst, const GenericArray src, u64 item_size) {
wapp_runtime_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL"); wapp_runtime_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL");
_array_validate(dst, item_size); _array_validate(dst, item_size);
_array_validate(src, item_size); _array_validate(src, item_size);
_array_clear(dst, item_size); _array_clear(dst, item_size);
u64 copy_count = src->count < dst->capacity ? src->count : dst->capacity;
memcpy(dst->items, src->items, copy_count * src->item_size); ArrayHeader *src_header = _array_header(src);
dst->count = copy_count; ArrayHeader *dst_header = _array_header(dst);
u64 copy_count = src_header->count < dst_header->capacity ? src_header->count : dst_header->capacity;
memcpy((void *)dst, (void *)src, copy_count * src_header->item_size);
dst_header->count = copy_count;
} }
GenericArray *_array_append_alloc(const Allocator *allocator, GenericArray *array, void *value, u64 item_size) { GenericArray _array_append_alloc(const Allocator *allocator, GenericArray array, void *value,
ArrayInitFlags flags, u64 item_size) {
wapp_runtime_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL"); wapp_runtime_assert(allocator != NULL && array != NULL, "`allocator` and `array` should not be NULL");
_array_validate(array, item_size); _array_validate(array, item_size);
GenericArray *output = array; GenericArray output = array;
if (array->count >= array->capacity) { ArrayHeader *header = _array_header(array);
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(array->capacity * 2); if (header->count >= header->capacity) {
output = (GenericArray *)_array_alloc_capacity(allocator, new_capacity, array->item_size, false); u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(header->capacity * 2);
output = (GenericArray )_array_alloc_capacity(allocator, new_capacity, flags,
header->item_size);
if (!output) { if (!output) {
output = array; output = array;
goto RETURN_ARRAY_APPEND_ALLOC; goto RETURN_ARRAY_APPEND_ALLOC;
@@ -76,21 +125,29 @@ GenericArray *_array_append_alloc(const Allocator *allocator, GenericArray *arra
_array_append_capped(output, value, item_size); _array_append_capped(output, value, item_size);
if ((flags & ARRAY_INIT_FILLED) == ARRAY_INIT_FILLED) {
_array_set_count(output, _array_capacity(output));
}
RETURN_ARRAY_APPEND_ALLOC: RETURN_ARRAY_APPEND_ALLOC:
return output; return output;
} }
GenericArray *_array_extend_alloc(const Allocator *allocator, GenericArray *dst, const GenericArray *src, u64 item_size) { GenericArray _array_extend_alloc(const Allocator *allocator, GenericArray dst, const GenericArray src,
ArrayInitFlags flags, u64 item_size) {
wapp_runtime_assert(allocator != NULL && dst != NULL && src != NULL, "`allocator`, `dst` and `src` should not be NULL"); wapp_runtime_assert(allocator != NULL && dst != NULL && src != NULL, "`allocator`, `dst` and `src` should not be NULL");
_array_validate(dst, item_size); _array_validate(dst, item_size);
_array_validate(src, item_size); _array_validate(src, item_size);
GenericArray *output = dst; GenericArray output = dst;
u64 remaining_capacity = dst->capacity - dst->count; ArrayHeader *src_header = _array_header(src);
if (src->count >= remaining_capacity) { ArrayHeader *dst_header = _array_header(dst);
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2); u64 remaining_capacity = dst_header->capacity - dst_header->count;
output = (GenericArray *)_array_alloc_capacity(allocator, new_capacity, dst->item_size, false); if (src_header->count >= remaining_capacity) {
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst_header->capacity * 2);
output = (GenericArray )_array_alloc_capacity(allocator, new_capacity,
flags, dst_header->item_size);
if (!output) { if (!output) {
output = dst; output = dst;
goto RETURN_ARRAY_EXTEND_ALLOC; goto RETURN_ARRAY_EXTEND_ALLOC;
@@ -100,20 +157,28 @@ GenericArray *_array_extend_alloc(const Allocator *allocator, GenericArray *dst,
_array_extend_capped(output, src, item_size); _array_extend_capped(output, src, item_size);
if ((flags & ARRAY_INIT_FILLED) == ARRAY_INIT_FILLED) {
_array_set_count(output, _array_capacity(output));
}
RETURN_ARRAY_EXTEND_ALLOC: RETURN_ARRAY_EXTEND_ALLOC:
return output; return output;
} }
GenericArray *_array_copy_alloc(const Allocator *allocator, GenericArray *dst, const GenericArray *src, u64 item_size) { GenericArray _array_copy_alloc(const Allocator *allocator, GenericArray dst, const GenericArray src,
ArrayInitFlags flags, u64 item_size) {
wapp_runtime_assert(allocator != NULL && dst != NULL && src != NULL, "`allocator`, `dst` and `src` should not be NULL"); wapp_runtime_assert(allocator != NULL && dst != NULL && src != NULL, "`allocator`, `dst` and `src` should not be NULL");
_array_validate(dst, item_size); _array_validate(dst, item_size);
_array_validate(src, item_size); _array_validate(src, item_size);
GenericArray *output = dst; GenericArray output = dst;
if (src->count >= dst->capacity) { ArrayHeader *src_header = _array_header(src);
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst->capacity * 2); ArrayHeader *dst_header = _array_header(dst);
output = (GenericArray *)_array_alloc_capacity(allocator, new_capacity, src->item_size, false); if (src_header->count >= dst_header->capacity) {
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(dst_header->capacity * 2);
output = (GenericArray )_array_alloc_capacity(allocator, new_capacity,
flags, src_header->item_size);
if (!output) { if (!output) {
output = dst; output = dst;
goto RETURN_ARRAY_COPY_ALLOC; goto RETURN_ARRAY_COPY_ALLOC;
@@ -122,52 +187,80 @@ GenericArray *_array_copy_alloc(const Allocator *allocator, GenericArray *dst, c
_array_copy_capped(output, src, item_size); _array_copy_capped(output, src, item_size);
if ((flags & ARRAY_INIT_FILLED) == ARRAY_INIT_FILLED) {
_array_set_count(output, _array_capacity(output));
}
RETURN_ARRAY_COPY_ALLOC: RETURN_ARRAY_COPY_ALLOC:
return output; return output;
} }
void *_array_pop(GenericArray *array, u64 item_size) { void *_array_pop(GenericArray array, u64 item_size) {
wapp_runtime_assert(array != NULL, "`array` should not be NULL"); wapp_runtime_assert(array != NULL, "`array` should not be NULL");
_array_validate(array, item_size); _array_validate(array, item_size);
if (array->count == 0) { return NULL; } ArrayHeader *header = _array_header(array);
if (header->count == 0) { return NULL; }
u64 index = array->count - 1; u64 index = header->count - 1;
void *out = _array_get(array, index, item_size); void *out = _array_get(array, index, item_size);
--(array->count); --(header->count);
return out; return out;
} }
void _array_clear(GenericArray *array, u64 item_size) { void _array_clear(GenericArray array, u64 item_size) {
wapp_runtime_assert(array != NULL, "`array` should not be NULL"); wapp_runtime_assert(array != NULL, "`array` should not be NULL");
_array_validate(array, item_size); _array_validate(array, item_size);
array->count = 0; ArrayHeader *header = _array_header(array);
header->count = 0;
} }
GenericArray *_array_alloc_capacity(const Allocator *allocator, u64 capacity, u64 item_size, b8 fill) { u64 _array_calc_alloc_size(u64 capacity, u64 item_size) {
return sizeof(ArrayHeader) + item_size * capacity;
}
GenericArray _array_alloc_capacity(const Allocator *allocator, u64 capacity, ArrayInitFlags flags,
u64 item_size) {
wapp_runtime_assert(allocator != NULL, "`allocator` should not be NULL"); wapp_runtime_assert(allocator != NULL, "`allocator` should not be NULL");
GenericArray *output = NULL; GenericArray output = NULL;
u64 allocation_size = sizeof(GenericArray) + item_size * capacity; u64 allocation_size = _array_calc_alloc_size(capacity, item_size);
void *buffer = wapp_mem_allocator_alloc(allocator, allocation_size);
output = wapp_mem_allocator_alloc(allocator, allocation_size); if (!buffer) {
if (!output) {
goto RETURN_ARRAY_ALLOC; goto RETURN_ARRAY_ALLOC;
} }
output->magic = WAPP_ARRAY_MAGIC; output = _array_from_preallocated_buffer(buffer, allocation_size, flags, item_size);
output->count = fill ? capacity : 0;
output->capacity = capacity;
output->item_size = item_size;
output->items = (void *)(output + 1);
RETURN_ARRAY_ALLOC: RETURN_ARRAY_ALLOC:
return output; return output;
} }
wapp_persist inline void _array_validate(const GenericArray *array, u64 item_size) {
wapp_runtime_assert(WAPP_ARRAY_MAGIC == array->magic, "`array` is not a valid wapp array"); GenericArray _array_from_preallocated_buffer(void *buffer, u64 buffer_size, ArrayInitFlags flags,
wapp_runtime_assert(item_size == array->item_size, "Invalid item type provided"); u64 item_size) {
wapp_runtime_assert(buffer != NULL, "`buffer` should not be NULL");
i64 data_buffer_size = (i64)buffer_size - (i64)(sizeof(ArrayHeader));
if (data_buffer_size <= 0) {
return NULL;
}
u64 item_capacity = (u64)data_buffer_size / item_size;
ArrayHeader *header = (ArrayHeader *)buffer;
GenericArray output = (u8 *)(header + 1);
header->magic = WAPP_ARRAY_MAGIC;
header->count = flags & ARRAY_INIT_FILLED ? item_capacity : 0;
header->capacity = item_capacity;
header->item_size = item_size;
return output;
}
wapp_persist inline void _array_validate(const GenericArray array, u64 item_size) {
ArrayHeader *header = _array_header(array);
wapp_runtime_assert(WAPP_ARRAY_MAGIC == header->magic, "`array` is not a valid wapp array");
wapp_runtime_assert(item_size == header->item_size, "Invalid item type provided");
} }

View File

@@ -17,144 +17,197 @@ BEGIN_C_LINKAGE
#define _calc_array_count(TYPE, ...) wapp_misc_utils_va_args_count(TYPE, __VA_ARGS__) #define _calc_array_count(TYPE, ...) wapp_misc_utils_va_args_count(TYPE, __VA_ARGS__)
#define _calc_array_capacity(TYPE, ...) wapp_misc_utils_u64_round_up_pow2(_calc_array_count(TYPE, __VA_ARGS__) * 2) #define _calc_array_capacity(TYPE, ...) wapp_misc_utils_u64_round_up_pow2(_calc_array_count(TYPE, __VA_ARGS__) * 2)
#define wapp_array_alloc_capacity(ELEM_TYPE, ARRAY_TYPE, ALLOCATOR_PTR, CAPACITY, FILL) \ typedef struct Str8 Str8;
((ARRAY_TYPE *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, sizeof(ELEM_TYPE), FILL))
#define WAPP_DEF_ARRAY_TYPE(T, NAME) \ // NOTE (Abdelrahman): Typedefs to distinguish arrays from regular pointers
typedef struct { \ typedef void *GenericArray;
u64 magic; \ typedef void **VoidPtrArray;
u64 count; \ typedef c8 *C8Array;
u64 capacity; \ typedef c16 *C16Array;
u64 item_size; \ typedef c32 *C32Array;
T *items; \ typedef u8 *U8Array;
} NAME typedef u16 *U16Array;
typedef u32 *U32Array;
typedef u64 *U64Array;
typedef b8 *B8Array;
typedef i8 *I8Array;
typedef i16 *I16Array;
typedef i32 *I32Array;
typedef i64 *I64Array;
typedef f32 *F32Array;
typedef f64 *F64Array;
typedef f128 *F128Array;
typedef uptr *UptrArray;
typedef iptr *IptrArray;
typedef Str8 *Str8Array;
typedef enum {
ARRAY_INIT_NONE = 0,
ARRAY_INIT_FILLED = 1 << 1,
} ArrayInitFlags;
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
#define wapp_array(ELEM_TYPE, ARRAY_TYPE, ...) ([&]() { \ #define wapp_array(TYPE, ...) ([&]() { \
wapp_persist ELEM_TYPE items[sizeof(ELEM_TYPE) == sizeof(*((ARRAY_TYPE{}).items)) ? \ u64 capacity = _calc_array_capacity(TYPE, __VA_ARGS__); \
_calc_array_capacity(ELEM_TYPE, __VA_ARGS__) : -1 \ \
] = {__VA_ARGS__}; \ TYPE items[_calc_array_capacity(TYPE, __VA_ARGS__)] = {__VA_ARGS__}; \
\ \
return ARRAY_TYPE{ \ wapp_persist u8 array[ \
WAPP_ARRAY_MAGIC, \ sizeof(ArrayHeader) + _calc_array_capacity(TYPE, __VA_ARGS__) * sizeof(TYPE) \
_calc_array_count(ELEM_TYPE, __VA_ARGS__), \ ] = {0}; \
_calc_array_capacity(ELEM_TYPE, __VA_ARGS__), \ ArrayHeader *header = (ArrayHeader *)array; \
sizeof(ELEM_TYPE), \ header->magic = WAPP_ARRAY_MAGIC; \
items, \ header->count = _calc_array_count(TYPE, __VA_ARGS__); \
}; \ header->capacity = _calc_array_capacity(TYPE, __VA_ARGS__); \
header->item_size = sizeof(TYPE); \
\
u8 *buf = (u8 *)(header + 1); \
memcpy(buf, items, capacity * sizeof(TYPE)); \
return (TYPE *)buf; \
}()) }())
#define wapp_array_with_capacity(ELEM_TYPE, ARRAY_TYPE, CAPACITY, FILL) ([&]() { \ #define wapp_array_with_capacity(TYPE, CAPACITY, FLAGS) ([&]() { \
wapp_persist ELEM_TYPE items[sizeof(ELEM_TYPE) == sizeof(*((ARRAY_TYPE{}).items)) ? \ wapp_persist u8 array[ \
CAPACITY : -1] = {}; \ sizeof(ArrayHeader) + CAPACITY * sizeof(TYPE) \
\ ] = {0}; \
return ARRAY_TYPE{ \ ArrayHeader *header = (ArrayHeader *)array; \
WAPP_ARRAY_MAGIC, \ header->magic = WAPP_ARRAY_MAGIC; \
FILL ? CAPACITY : 0, \ header->count = (FLAGS & ARRAY_INIT_FILLED) ? CAPACITY : 0; \
CAPACITY, \ header->capacity = CAPACITY; \
sizeof(ELEM_TYPE), \ header->item_size = sizeof(TYPE); \
items, \ \
}; \ return (TYPE *)(header + 1); \
}()) }())
#define wapp_array_pop(ELEM_TYPE, ARRAY_PTR) ([&]() { \ #define wapp_array_pop(TYPE, ARRAY) ([&]() { \
if (ARRAY_PTR == NULL || (ARRAY_PTR)->count == 0) { \ if (ARRAY == NULL || _array_count((GenericArray)ARRAY) == 0) { \
ELEM_TYPE result{}; \ TYPE result{}; \
return result; \ return result; \
} \ } \
\ \
return *((ELEM_TYPE *)_array_pop((GenericArray *)ARRAY_PTR, sizeof(ELEM_TYPE))); \ return *((TYPE *)_array_pop((GenericArray)ARRAY, sizeof(TYPE))); \
}()) }())
#else #else
#define wapp_array(ELEM_TYPE, ARRAY_TYPE, ...) \ #define _stack_array(TYPE, SIZE) struct {ArrayHeader header; \
((ARRAY_TYPE){ \ TYPE items[SIZE]; \
.magic = WAPP_ARRAY_MAGIC, \ wapp_misc_utils_reserve_padding(sizeof(ArrayHeader) + \
.count = _calc_array_count(ELEM_TYPE, __VA_ARGS__), \ sizeof(TYPE) * SIZE);}
.capacity = _calc_array_capacity(ELEM_TYPE, __VA_ARGS__), \ #define wapp_array(TYPE, ...) \
.item_size = sizeof(ELEM_TYPE), \ ((TYPE *)( \
.items = (ELEM_TYPE[sizeof(ELEM_TYPE) == sizeof(*((ARRAY_TYPE){0}.items)) ? \ (_stack_array(TYPE, _calc_array_capacity(TYPE, __VA_ARGS__))){ \
_calc_array_capacity(ELEM_TYPE, __VA_ARGS__) : \ .header = { \
-1]){__VA_ARGS__} \ .magic = WAPP_ARRAY_MAGIC, \
}) .count = _calc_array_count(TYPE, __VA_ARGS__), \
#define wapp_array_with_capacity(ELEM_TYPE, ARRAY_TYPE, CAPACITY, FILL) \ .capacity = _calc_array_capacity(TYPE, __VA_ARGS__), \
((ARRAY_TYPE){ \ .item_size = sizeof(TYPE), \
.magic = WAPP_ARRAY_MAGIC, \ }, \
.count = FILL ? CAPACITY : 0, \ .items = {__VA_ARGS__}, \
.capacity = CAPACITY, \ }.items \
.item_size = sizeof(ELEM_TYPE), \ ))
.items = (ELEM_TYPE[sizeof(ELEM_TYPE) == sizeof(*((ARRAY_TYPE){0}.items)) ? \ #define wapp_array_with_capacity(TYPE, CAPACITY, FLAGS) \
CAPACITY : -1]){0} \ ((TYPE *)( \
}) (_stack_array(TYPE, CAPACITY)){ \
#define wapp_array_pop(ELEM_TYPE, ARRAY_PTR) \ .header = { \
(ARRAY_PTR != NULL && (ARRAY_PTR)->count > 0 ? \ .magic = WAPP_ARRAY_MAGIC, \
*((ELEM_TYPE *)_array_pop((GenericArray *)ARRAY_PTR, sizeof(ELEM_TYPE))) : \ .count = (FLAGS & ARRAY_INIT_FILLED) ? CAPACITY : 0, \
(ELEM_TYPE){0} \ .capacity = CAPACITY, \
.item_size = sizeof(TYPE), \
}, \
.items = {0}, \
}.items \
))
#define wapp_array_pop(TYPE, ARRAY) \
(ARRAY == NULL || _array_count((GenericArray)ARRAY) == 0 ? \
(TYPE){0} : \
*((TYPE *)_array_pop((GenericArray)ARRAY, sizeof(TYPE))) \
) )
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
#define wapp_array_get(ELEM_TYPE, ARRAY_PTR, INDEX) \ #define wapp_array_count(ARRAY) \
((ELEM_TYPE *)_array_get((GenericArray *)ARRAY_PTR, INDEX, sizeof(ELEM_TYPE))) (_array_count((GenericArray)ARRAY))
#define wapp_array_set(ELEM_TYPE, ARRAY_PTR, INDEX, VALUE_PTR) \ #define wapp_array_capacity(ARRAY) \
_array_set((GenericArray *)ARRAY_PTR, INDEX, (void *)VALUE_PTR, sizeof(ELEM_TYPE)) (_array_capacity((GenericArray)ARRAY))
#define wapp_array_append_capped(ELEM_TYPE, ARRAY_PTR, VALUE_PTR) \ #define wapp_array_item_size(ARRAY) \
_array_append_capped((GenericArray *)ARRAY_PTR, (void *)VALUE_PTR, sizeof(ELEM_TYPE)) (_array_item_size((GenericArray)ARRAY))
#define wapp_array_extend_capped(ELEM_TYPE, DST_ARRAY_PTR, SRC_ARRAY_PTR) \ #define wapp_array_set_count(ARRAY, COUNT) \
_array_extend_capped( \ (_array_set_count((GenericArray)ARRAY, COUNT))
(GenericArray *)DST_ARRAY_PTR, (GenericArray *)SRC_ARRAY_PTR, sizeof(ELEM_TYPE) \ #define wapp_array_get(TYPE, ARRAY, INDEX) \
) ((TYPE *)_array_get((GenericArray)ARRAY, \
#define wapp_array_copy_capped(ELEM_TYPE, DST_ARRAY_PTR, SRC_ARRAY_PTR) \ INDEX, \
_array_copy_capped( \ sizeof(TYPE)))
(GenericArray *)DST_ARRAY_PTR, (GenericArray *)SRC_ARRAY_PTR, sizeof(ELEM_TYPE) \ #define wapp_array_set(TYPE, ARRAY, INDEX, VALUE_PTR) \
) (_array_set((GenericArray)ARRAY, \
#define wapp_array_append_alloc(ELEM_TYPE, ARRAY_TYPE, ALLOCATOR_PTR, ARRAY_PTR, VALUE_PTR) \ INDEX, \
(ARRAY_TYPE *)_array_append_alloc( \ (u8 *)VALUE_PTR, \
ALLOCATOR_PTR, (GenericArray *)ARRAY_PTR, (void *)VALUE_PTR, sizeof(ELEM_TYPE) \ sizeof(TYPE)))
) #define wapp_array_append_capped(TYPE, ARRAY, VALUE_PTR) \
#define wapp_array_extend_alloc(ELEM_TYPE, ARRAY_TYPE, ALLOCATOR_PTR, DST_ARRAY_PTR, SRC_ARRAY_PTR) \ (_array_append_capped((GenericArray)ARRAY, \
(ARRAY_TYPE *)_array_extend_alloc( \ (u8 *)VALUE_PTR, \
ALLOCATOR_PTR, (GenericArray *)DST_ARRAY_PTR, (GenericArray *)SRC_ARRAY_PTR, sizeof(ELEM_TYPE) \ sizeof(TYPE)))
) #define wapp_array_extend_capped(TYPE, DST_ARRAY, SRC_ARRAY) \
#define wapp_array_copy_alloc(ELEM_TYPE, ARRAY_TYPE, ALLOCATOR_PTR, DST_ARRAY_PTR, SRC_ARRAY_PTR) \ (_array_extend_capped((GenericArray)DST_ARRAY, \
(ARRAY_TYPE *)_array_copy_alloc( \ (GenericArray)SRC_ARRAY, \
ALLOCATOR_PTR, (GenericArray *)DST_ARRAY_PTR, (GenericArray *)SRC_ARRAY_PTR, sizeof(ELEM_TYPE) \ sizeof(TYPE)))
) #define wapp_array_copy_capped(TYPE, DST_ARRAY, SRC_ARRAY) \
#define wapp_array_clear(ELEM_TYPE, ARRAY_PTR) \ (_array_copy_capped((GenericArray)DST_ARRAY, \
_array_clear((GenericArray *)ARRAY_PTR, sizeof(ELEM_TYPE)) (GenericArray)SRC_ARRAY, \
sizeof(TYPE)))
#define wapp_array_append_alloc(TYPE, ALLOCATOR_PTR, ARRAY, VALUE_PTR, FLAGS) \
((TYPE *)_array_append_alloc(ALLOCATOR_PTR, \
(GenericArray)ARRAY, \
(u8 *)VALUE_PTR, \
FLAGS, \
sizeof(TYPE)))
#define wapp_array_extend_alloc(TYPE, ALLOCATOR_PTR, DST_ARRAY, SRC_ARRAY, FLAGS) \
((TYPE *)_array_extend_alloc(ALLOCATOR_PTR, \
(GenericArray)DST_ARRAY, \
(GenericArray)SRC_ARRAY, \
FLAGS, \
sizeof(TYPE)))
#define wapp_array_copy_alloc(TYPE, ALLOCATOR_PTR, DST_ARRAY, SRC_ARRAY, FLAGS) \
((TYPE *)_array_copy_alloc(ALLOCATOR_PTR, \
(GenericArray)DST_ARRAY, \
(GenericArray)SRC_ARRAY, \
FLAGS, \
sizeof(TYPE)))
#define wapp_array_clear(TYPE, ARRAY) \
(_array_clear((GenericArray)ARRAY, \
sizeof(TYPE)))
#define wapp_array_calc_alloc_size(TYPE, CAPACITY) _array_calc_alloc_size(CAPACITY, sizeof(TYPE))
#define wapp_array_alloc_capacity(TYPE, ALLOCATOR_PTR, CAPACITY, FLAGS) \
((TYPE *)_array_alloc_capacity(ALLOCATOR_PTR, CAPACITY, FLAGS, sizeof(TYPE)))
#define wapp_array_from_preallcated_buffer(TYPE, BUFFER, BUFFER_SIZE) \
((TYPE *)_array_from_preallcated_buffer(BUFFER, BUFFER_SIZE, sizeof(TYPE)))
WAPP_DEF_ARRAY_TYPE(void, GenericArray);
void *_array_get(GenericArray *array, u64 index, u64 item_size); typedef struct header ArrayHeader;
void _array_set(GenericArray *array, u64 index, void *value, u64 item_size); struct header {
void _array_append_capped(GenericArray *array, void *value, u64 item_size); u64 magic;
void _array_extend_capped(GenericArray *dst, const GenericArray *src, u64 item_size); u64 count;
void _array_copy_capped(GenericArray *dst, const GenericArray *src, u64 item_size); u64 capacity;
GenericArray *_array_append_alloc(const Allocator *allocator, GenericArray *array, void *value, u64 item_size); u64 item_size;
GenericArray *_array_extend_alloc(const Allocator *allocator, GenericArray *dst, const GenericArray *src, u64 item_size); };
GenericArray *_array_copy_alloc(const Allocator *allocator, GenericArray *dst, const GenericArray *src, u64 item_size);
void *_array_pop(GenericArray *array, u64 item_size);
void _array_clear(GenericArray *array, u64 item_size);
GenericArray *_array_alloc_capacity(const Allocator *allocator, u64 capacity, u64 item_size, b8 fill);
// Base array types u64 _array_count(GenericArray array);
typedef struct str8 Str8; u64 _array_capacity(GenericArray array);
u64 _array_item_size(GenericArray array);
WAPP_DEF_ARRAY_TYPE(void *, VoidPtrArray); void _array_set_count(GenericArray array, u64 count);
WAPP_DEF_ARRAY_TYPE(c8 , C8Array); void *_array_get(GenericArray array, u64 index, u64 item_size);
WAPP_DEF_ARRAY_TYPE(c16 , C16Array); void _array_set(GenericArray array, u64 index, void *value, u64 item_size);
WAPP_DEF_ARRAY_TYPE(c32 , C32Array); void _array_append_capped(GenericArray array, void *value, u64 item_size);
WAPP_DEF_ARRAY_TYPE(u8 , U8Array); void _array_extend_capped(GenericArray dst, const GenericArray src, u64 item_size);
WAPP_DEF_ARRAY_TYPE(u16 , U16Array); void _array_copy_capped(GenericArray dst, const GenericArray src, u64 item_size);
WAPP_DEF_ARRAY_TYPE(u32 , U32Array); GenericArray _array_append_alloc(const Allocator *allocator, GenericArray array, void *value,
WAPP_DEF_ARRAY_TYPE(u64 , U64Array); ArrayInitFlags flags, u64 item_size);
WAPP_DEF_ARRAY_TYPE(b8 , B8Array); GenericArray _array_extend_alloc(const Allocator *allocator, GenericArray dst, const GenericArray src,
WAPP_DEF_ARRAY_TYPE(i8 , I8Array); ArrayInitFlags flags, u64 item_size);
WAPP_DEF_ARRAY_TYPE(i16 , I16Array); GenericArray _array_copy_alloc(const Allocator *allocator, GenericArray dst, const GenericArray src,
WAPP_DEF_ARRAY_TYPE(i32 , I32Array); ArrayInitFlags flags, u64 item_size);
WAPP_DEF_ARRAY_TYPE(i64 , I64Array); void *_array_pop(GenericArray array, u64 item_size);
WAPP_DEF_ARRAY_TYPE(f32 , F32Array); void _array_clear(GenericArray array, u64 item_size);
WAPP_DEF_ARRAY_TYPE(f64 , F64Array); u64 _array_calc_alloc_size(u64 capacity, u64 item_size);
WAPP_DEF_ARRAY_TYPE(f128 , F128Array); GenericArray _array_alloc_capacity(const Allocator *allocator, u64 capacity, ArrayInitFlags flags,
WAPP_DEF_ARRAY_TYPE(uptr , UptrArray); u64 item_size);
WAPP_DEF_ARRAY_TYPE(iptr , IptrArray); GenericArray _array_from_preallocated_buffer(void *buffer, u64 buffer_size, ArrayInitFlags flags,
WAPP_DEF_ARRAY_TYPE(Str8 , Str8Array); u64 item_size);
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE

View File

@@ -18,22 +18,23 @@ GenericList *_dbl_list_alloc(const Allocator *allocator, u64 item_size) {
if (!list) { goto DBL_LIST_ALLOC_RETURN; } if (!list) { goto DBL_LIST_ALLOC_RETURN; }
memset((void *)list, 0, sizeof(GenericList)); memset((void *)list, 0, sizeof(GenericList));
list->magic = WAPP_DBL_LIST_MAGIC; list->magic = WAPP_DBL_LIST_MAGIC;
list->item_size = item_size; list->item_size = item_size;
DBL_LIST_ALLOC_RETURN: DBL_LIST_ALLOC_RETURN:
return list; return list;
} }
GenericNode *_dbl_list_node_alloc(const Allocator *allocator, u64 item_size) { GenericNode *_dbl_list_node_alloc(const Allocator *allocator, void *item, u64 item_size) {
wapp_debug_assert(allocator != NULL, "`allocator` should not be NULL"); wapp_debug_assert(allocator != NULL, "`allocator` should not be NULL");
GenericNode *node = wapp_mem_allocator_alloc(allocator, sizeof(GenericNode)); GenericNode *node = wapp_mem_allocator_alloc(allocator, sizeof(GenericNode));
if (!node) { goto DBL_LIST_NODE_ALLOC_RETURN; } if (!node) { goto DBL_LIST_NODE_ALLOC_RETURN; }
memset((void *)node, 0, sizeof(GenericNode)); memset((void *)node, 0, sizeof(GenericNode));
node->magic = WAPP_DBL_NODE_MAGIC; node->item = item;
node->item_size = item_size; node->header.magic = WAPP_DBL_NODE_MAGIC;
node->header.item_size = item_size;
DBL_LIST_NODE_ALLOC_RETURN: DBL_LIST_NODE_ALLOC_RETURN:
return node; return node;
@@ -44,10 +45,10 @@ GenericNode *_dbl_list_get(const GenericList *list, u64 index, u64 item_size) {
_dbl_list_validate(list, item_size); _dbl_list_validate(list, item_size);
wapp_runtime_assert(index < list->node_count, "`index` is out of bounds"); wapp_runtime_assert(index < list->node_count, "`index` is out of bounds");
GenericNode *output = NULL; GenericNode *output = NULL;
GenericNode *current = list->first; GenericNode *current = list->first;
for (u64 i = 1; i <= index; ++i) { for (u64 i = 1; i <= index; ++i) {
current = current->next; current = current->header.next;
} }
output = current; output = current;
@@ -71,11 +72,11 @@ void _dbl_list_push_front(GenericList *list, GenericNode *node, u64 item_size) {
GenericNode *first = list->first; GenericNode *first = list->first;
if (first) { if (first) {
first->prev = node_list.last; first->header.prev = node_list.last;
} }
list->first = node_list.first; list->first = node_list.first;
node_list.last->next = first; node_list.last->header.next = first;
} }
void _dbl_list_push_back(GenericList *list, GenericNode *node, u64 item_size) { void _dbl_list_push_back(GenericList *list, GenericNode *node, u64 item_size) {
@@ -94,11 +95,11 @@ void _dbl_list_push_back(GenericList *list, GenericNode *node, u64 item_size) {
GenericNode *last = list->last; GenericNode *last = list->last;
if (last) { if (last) {
last->next = node_list.first; last->header.next = node_list.first;
} }
list->last = node_list.last; list->last = node_list.last;
node_list.first->prev = last; node_list.first->header.prev = last;
} }
void _dbl_list_insert(GenericList *list, GenericNode *node, u64 index, u64 item_size) { void _dbl_list_insert(GenericList *list, GenericNode *node, u64 index, u64 item_size) {
@@ -123,13 +124,13 @@ void _dbl_list_insert(GenericList *list, GenericNode *node, u64 index, u64 item_
list->node_count += node_list.node_count; list->node_count += node_list.node_count;
GenericNode *prev = dst_node->prev; GenericNode *prev = dst_node->header.prev;
dst_node->prev = node_list.last; dst_node->header.prev = node_list.last;
prev->next = node_list.first; prev->header.next = node_list.first;
node_list.first->prev = prev; node_list.first->header.prev = prev;
node_list.last->next = dst_node; node_list.last->header.next = dst_node;
} }
GenericNode *_dbl_list_pop_front(GenericList *list, u64 item_size) { GenericNode *_dbl_list_pop_front(GenericList *list, u64 item_size) {
@@ -139,22 +140,22 @@ GenericNode *_dbl_list_pop_front(GenericList *list, u64 item_size) {
GenericNode *output = NULL; GenericNode *output = NULL;
if (list->node_count == 0) { if (list->node_count == 0) {
goto RETURN_I32_LIST_POP_FRONT; goto RETURN_LIST_POP_FRONT;
} }
output = list->first; output = list->first;
if (list->node_count == 1) { if (list->node_count == 1) {
*list = (GenericList){.magic = WAPP_DBL_LIST_MAGIC, .item_size = item_size}; *list = (GenericList){.magic = WAPP_DBL_LIST_MAGIC, .item_size = item_size};
goto RETURN_I32_LIST_POP_FRONT; goto RETURN_LIST_POP_FRONT;
} }
--(list->node_count); --(list->node_count);
list->first = output->next; list->first = output->header.next;
output->prev = output->next = NULL; output->header.prev = output->header.next = NULL;
RETURN_I32_LIST_POP_FRONT: RETURN_LIST_POP_FRONT:
return output; return output;
} }
@@ -165,22 +166,22 @@ GenericNode *_dbl_list_pop_back(GenericList *list, u64 item_size) {
GenericNode *output = NULL; GenericNode *output = NULL;
if (list->node_count == 0) { if (list->node_count == 0) {
goto RETURN_I32_LIST_POP_BACK; goto RETURN_LIST_POP_BACK;
} }
output = list->last; output = list->last;
if (list->node_count == 1) { if (list->node_count == 1) {
*list = (GenericList){.magic = WAPP_DBL_LIST_MAGIC, .item_size = item_size}; *list = (GenericList){.magic = WAPP_DBL_LIST_MAGIC, .item_size = item_size};
goto RETURN_I32_LIST_POP_BACK; goto RETURN_LIST_POP_BACK;
} }
--(list->node_count); --(list->node_count);
list->last = output->prev; list->last = output->header.prev;
output->prev = output->next = NULL; output->header.prev = output->header.next = NULL;
RETURN_I32_LIST_POP_BACK: RETURN_LIST_POP_BACK:
return output; return output;
} }
@@ -192,25 +193,25 @@ GenericNode *_dbl_list_remove(GenericList *list, u64 index, u64 item_size) {
if (index == 0) { if (index == 0) {
output = _dbl_list_pop_front(list, item_size); output = _dbl_list_pop_front(list, item_size);
goto RETURN_I32_LIST_REMOVE; goto RETURN_LIST_REMOVE;
} else if (index == list->node_count) { } else if (index == list->node_count) {
output = _dbl_list_pop_back(list, item_size); output = _dbl_list_pop_back(list, item_size);
goto RETURN_I32_LIST_REMOVE; goto RETURN_LIST_REMOVE;
} }
output = _dbl_list_get(list, index, item_size); output = _dbl_list_get(list, index, item_size);
if (!output) { if (!output) {
goto RETURN_I32_LIST_REMOVE; goto RETURN_LIST_REMOVE;
} }
output->prev->next = output->next; output->header.prev->header.next = output->header.next;
output->next->prev = output->prev; output->header.next->header.prev = output->header.prev;
--(list->node_count); --(list->node_count);
output->prev = output->next = NULL; output->header.prev = output->header.next = NULL;
RETURN_I32_LIST_REMOVE: RETURN_LIST_REMOVE:
return output; return output;
} }
@@ -226,20 +227,20 @@ void _dbl_list_empty(GenericList *list, u64 item_size) {
wapp_intern GenericList _node_to_list(GenericNode *node, u64 item_size) { wapp_intern GenericList _node_to_list(GenericNode *node, u64 item_size) {
GenericList output = { GenericList output = {
.magic = WAPP_DBL_LIST_MAGIC, .magic = WAPP_DBL_LIST_MAGIC,
.first = node, .first = node,
.last = node, .last = node,
.node_count = 1, .node_count = 1,
.item_size = item_size, .item_size = item_size,
}; };
while (output.first->prev != NULL) { while (output.first->header.prev != NULL) {
output.first = output.first->prev; output.first = output.first->header.prev;
++(output.node_count); ++(output.node_count);
} }
while (output.last->next != NULL) { while (output.last->header.next != NULL) {
output.last = output.last->next; output.last = output.last->header.next;
++(output.node_count); ++(output.node_count);
} }
@@ -252,7 +253,7 @@ wapp_intern inline void _dbl_list_validate(const GenericList *list, u64 item_siz
} }
wapp_intern inline void _dbl_list_node_validate(const GenericList *list, const GenericNode *node, u64 item_size) { wapp_intern inline void _dbl_list_node_validate(const GenericList *list, const GenericNode *node, u64 item_size) {
wapp_runtime_assert(node->magic == WAPP_DBL_NODE_MAGIC, "`node` isn't a valid wapp node type"); wapp_runtime_assert(node->header.magic == WAPP_DBL_NODE_MAGIC, "`node` isn't a valid wapp node type");
wapp_runtime_assert(list->item_size == node->item_size, "Mismatched `list` and `node` types"); wapp_runtime_assert(list->item_size == node->header.item_size, "Mismatched `list` and `node` types");
wapp_runtime_assert(node->item_size == item_size, "Invalid item provided"); wapp_runtime_assert(node->header.item_size == item_size, "Invalid item provided");
} }

View File

@@ -14,94 +14,168 @@ BEGIN_C_LINKAGE
#define WAPP_DBL_LIST_MAGIC (u64)0x57415f444c5354 #define WAPP_DBL_LIST_MAGIC (u64)0x57415f444c5354
#define WAPP_DBL_NODE_MAGIC (u64)0x57415f444e44 #define WAPP_DBL_NODE_MAGIC (u64)0x57415f444e44
#define WAPP_DEF_DBL_LIST_TYPE(T, NODE_NAME, LIST_NAME) \ typedef struct GenericNode GenericNode;
typedef struct NODE_NAME NODE_NAME; \
struct NODE_NAME { \ typedef struct {
u64 magic; \ u64 magic;
T *item; \ u64 item_size;
NODE_NAME *prev; \ GenericNode *prev;
NODE_NAME *next; \ GenericNode *next;
u64 item_size; \ } NodeHeader;
}; \
\ struct GenericNode {
typedef struct { \ NodeHeader header;
u64 magic; \ void *item;
NODE_NAME *first; \ };
NODE_NAME *last; \
u64 node_count; \ typedef struct {
u64 item_size; \ u64 magic;
} LIST_NAME u64 node_count;
u64 item_size;
GenericNode *first;
GenericNode *last;
} GenericList;
// NOTE (Abdelrahman): GenericList typedefs for readability
typedef GenericList VoidPtrList;
typedef GenericList C8List;
typedef GenericList C16List;
typedef GenericList C32List;
typedef GenericList U8List;
typedef GenericList U16List;
typedef GenericList U32List;
typedef GenericList U64List;
typedef GenericList B8List;
typedef GenericList I8List;
typedef GenericList I16List;
typedef GenericList I32List;
typedef GenericList I64List;
typedef GenericList F32List;
typedef GenericList F64List;
typedef GenericList F128List;
typedef GenericList UptrList;
typedef GenericList IptrList;
typedef GenericList Str8List;
// NOTE (Abdelrahman): GenericNode typedefs for readability
typedef GenericNode VoidPtrNode;
typedef GenericNode C8Node;
typedef GenericNode C16Node;
typedef GenericNode C32Node;
typedef GenericNode U8Node;
typedef GenericNode U16Node;
typedef GenericNode U32Node;
typedef GenericNode U64Node;
typedef GenericNode B8Node;
typedef GenericNode I8Node;
typedef GenericNode I16Node;
typedef GenericNode I32Node;
typedef GenericNode I64Node;
typedef GenericNode F32Node;
typedef GenericNode F64Node;
typedef GenericNode F128Node;
typedef GenericNode UptrNode;
typedef GenericNode IptrNode;
typedef GenericNode Str8Node;
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
#define wapp_dbl_list(ELEM_TYPE, LIST_TYPE) \ #define wapp_dbl_list(TYPE) \
LIST_TYPE{WAPP_DBL_LIST_MAGIC, nullptr, nullptr, 0, sizeof(ELEM_TYPE)} GenericList{WAPP_DBL_LIST_MAGIC, 0, sizeof(TYPE), nullptr, nullptr}
#define wapp_dbl_list_node(ELEM_TYPE, NODE_TYPE, ELEM_PTR) \ #define _dbl_list_node(TYPE, ITEM_PTR) ([&]() { \
NODE_TYPE{WAPP_DBL_NODE_MAGIC, ELEM_PTR, nullptr, nullptr, sizeof(ELEM_TYPE)} wapp_persist GenericNode node = { \
NodeHeader{WAPP_DBL_NODE_MAGIC, sizeof(TYPE), nullptr, nullptr}, \
ITEM_PTR, \
}; \
\
return &node; \
}())
#else #else
#define wapp_dbl_list(ELEM_TYPE, LIST_TYPE) ( \ #define wapp_dbl_list(TYPE) ( \
(LIST_TYPE){.magic = WAPP_DBL_LIST_MAGIC, .item_size = sizeof(ELEM_TYPE)} \ (GenericList){.magic = WAPP_DBL_LIST_MAGIC, .item_size = sizeof(TYPE)} \
) )
#define wapp_dbl_list_node(ELEM_TYPE, NODE_TYPE, ELEM_PTR) ( \ #define _dbl_list_node(TYPE, ITEM_PTR) ( \
(NODE_TYPE){.magic = WAPP_DBL_NODE_MAGIC, .item = ELEM_PTR, .item_size = sizeof(ELEM_TYPE)} \ &((GenericNode){.header = {.magic = WAPP_DBL_NODE_MAGIC, .item_size = sizeof(TYPE)}, \
.item = ITEM_PTR}) \
) )
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
#define wapp_dbl_list_alloc(ELEM_TYPE, LIST_TYPE, ALLOCATOR) \ #define wapp_dbl_list_alloc(TYPE, ALLOCATOR) \
(LIST_TYPE *)_dbl_list_alloc(ALLOCATOR, sizeof(ELEM_TYPE)) (_dbl_list_alloc(ALLOCATOR, sizeof(TYPE)))
#define wapp_dbl_list_node_alloc(ELEM_TYPE, NODE_TYPE, ALLOCATOR) \ #define wapp_dbl_list_get(TYPE, LIST_PTR, ITEM_INDEX) \
(NODE_TYPE *)_dbl_list_node_alloc(ALLOCATOR, sizeof(ELEM_TYPE)) ((TYPE *)(_dbl_list_get(LIST_PTR, ITEM_INDEX, sizeof(TYPE))->item))
#define wapp_dbl_list_get(ELEM_TYPE, NODE_TYPE, LIST_PTR, ELEM_INDEX) \ #define wapp_dbl_list_get_node(TYPE, LIST_PTR, ITEM_INDEX) \
(NODE_TYPE *)_dbl_list_get((GenericList *)LIST_PTR, ELEM_INDEX, sizeof(ELEM_TYPE)) (_dbl_list_get(LIST_PTR, ITEM_INDEX, sizeof(TYPE)))
#define wapp_dbl_list_push_front(ELEM_TYPE, LIST_PTR, NODE_PTR) \ #define wapp_dbl_list_get_node_item(TYPE, NODE_PTR) \
_dbl_list_push_front((GenericList *)LIST_PTR, (GenericNode *)NODE_PTR, sizeof(ELEM_TYPE)) ((TYPE *)( \
#define wapp_dbl_list_push_back(ELEM_TYPE, LIST_PTR, NODE_PTR) \ (NODE_PTR == NULL) ? \
_dbl_list_push_back((GenericList *)LIST_PTR, (GenericNode *)NODE_PTR, sizeof(ELEM_TYPE)) NULL : \
#define wapp_dbl_list_insert(ELEM_TYPE, LIST_PTR, NODE_PTR, ELEM_INDEX) \ (NODE_PTR)->item \
_dbl_list_insert((GenericList *)LIST_PTR, (GenericNode *)NODE_PTR, ELEM_INDEX, sizeof(ELEM_TYPE)) ))
#define wapp_dbl_list_pop_front(ELEM_TYPE, NODE_TYPE, LIST_PTR) \ #define wapp_dbl_list_push_front(TYPE, LIST_PTR, ITEM_PTR) \
(NODE_TYPE *)_dbl_list_pop_front((GenericList *)LIST_PTR, sizeof(ELEM_TYPE)) (_dbl_list_push_front(LIST_PTR, _dbl_list_node(TYPE, ITEM_PTR), sizeof(TYPE)))
#define wapp_dbl_list_pop_back(ELEM_TYPE, NODE_TYPE, LIST_PTR) \ #define wapp_dbl_list_push_back(TYPE, LIST_PTR, ITEM_PTR) \
(NODE_TYPE *)_dbl_list_pop_back((GenericList *)LIST_PTR, sizeof(ELEM_TYPE)) (_dbl_list_push_back(LIST_PTR, _dbl_list_node(TYPE, ITEM_PTR), sizeof(TYPE)))
#define wapp_dbl_list_remove(ELEM_TYPE, NODE_TYPE, LIST_PTR, ELEM_INDEX) \ #define wapp_dbl_list_insert(TYPE, LIST_PTR, ITEM_PTR, ITEM_INDEX) \
(NODE_TYPE *)_dbl_list_remove((GenericList *)LIST_PTR, ELEM_INDEX, sizeof(ELEM_TYPE)) (_dbl_list_insert(LIST_PTR, _dbl_list_node(TYPE, ITEM_PTR), \
#define wapp_dbl_list_empty(ELEM_TYPE, LIST_PTR) \ ITEM_INDEX, sizeof(TYPE)))
_dbl_list_empty((GenericList *)LIST_PTR, sizeof(ELEM_TYPE)) #define wapp_dbl_list_push_front_alloc(TYPE, ALLOCATOR, LIST_PTR, ITEM_PTR) \
(_dbl_list_push_front(LIST_PTR, _dbl_list_node_alloc(ALLOCATOR, ITEM_PTR, sizeof(TYPE)), \
sizeof(TYPE)))
#define wapp_dbl_list_push_back_alloc(TYPE, ALLOCATOR, LIST_PTR, ITEM_PTR) \
(_dbl_list_push_back(LIST_PTR, _dbl_list_node_alloc(ALLOCATOR, ITEM_PTR, sizeof(TYPE)), \
sizeof(TYPE)))
#define wapp_dbl_list_insert_alloc(TYPE, ALLOCATOR, LIST_PTR, ITEM_PTR, ITEM_INDEX) \
(_dbl_list_insert(LIST_PTR, _dbl_list_node_alloc(ALLOCATOR, ITEM_PTR, sizeof(TYPE)), \
ITEM_INDEX, sizeof(TYPE)))
#define wapp_dbl_list_pop_front(TYPE, LIST_PTR) \
((TYPE *)( \
(LIST_PTR == NULL || (LIST_PTR)->node_count == 0) ? \
NULL : \
_dbl_list_pop_front(LIST_PTR, sizeof(TYPE))->item \
))
#define wapp_dbl_list_pop_back(TYPE, LIST_PTR) \
((TYPE *)( \
(LIST_PTR == NULL || (LIST_PTR)->node_count == 0) ? \
NULL : \
_dbl_list_pop_back(LIST_PTR, sizeof(TYPE))->item \
))
#define wapp_dbl_list_remove(TYPE, LIST_PTR, ITEM_INDEX) \
((TYPE *)( \
(LIST_PTR == NULL || (LIST_PTR)->node_count == 0 || ITEM_INDEX >= (LIST_PTR)->node_count) ? \
NULL : \
_dbl_list_remove(LIST_PTR, ITEM_INDEX, sizeof(TYPE))->item \
))
#define wapp_dbl_list_pop_front_node(TYPE, LIST_PTR) \
( \
(LIST_PTR == NULL || (LIST_PTR)->node_count == 0) ? \
NULL : \
_dbl_list_pop_front(LIST_PTR, sizeof(TYPE)) \
)
#define wapp_dbl_list_pop_back_node(TYPE, LIST_PTR) \
( \
(LIST_PTR == NULL || (LIST_PTR)->node_count == 0) ? \
NULL : \
_dbl_list_pop_back(LIST_PTR, sizeof(TYPE)) \
)
#define wapp_dbl_list_remove_node(TYPE, LIST_PTR, ITEM_INDEX) \
( \
(LIST_PTR == NULL || (LIST_PTR)->node_count == 0 || ITEM_INDEX >= (LIST_PTR)->node_count) ? \
NULL : \
_dbl_list_remove(LIST_PTR, ITEM_INDEX, sizeof(TYPE)) \
)
#define wapp_dbl_list_empty(TYPE, LIST_PTR) \
(_dbl_list_empty(LIST_PTR, sizeof(TYPE)))
WAPP_DEF_DBL_LIST_TYPE(void, GenericNode, GenericList); GenericList *_dbl_list_alloc(const Allocator *allocator, u64 item_size);
GenericNode *_dbl_list_node_alloc(const Allocator *allocator, void *item, u64 item_size);
GenericList *_dbl_list_alloc(const Allocator *allocator, u64 item_size); GenericNode *_dbl_list_get(const GenericList *list, u64 index, u64 item_size);
GenericNode *_dbl_list_node_alloc(const Allocator *allocator, u64 item_size); void _dbl_list_push_front(GenericList *list, GenericNode *node, u64 item_size);
GenericNode *_dbl_list_get(const GenericList *list, u64 index, u64 item_size); void _dbl_list_push_back(GenericList *list, GenericNode *node, u64 item_size);
void _dbl_list_push_front(GenericList *list, GenericNode *node, u64 item_size); void _dbl_list_insert(GenericList *list, GenericNode *node, u64 index, u64 item_size);
void _dbl_list_push_back(GenericList *list, GenericNode *node, u64 item_size); GenericNode *_dbl_list_pop_front(GenericList *list, u64 item_size);
void _dbl_list_insert(GenericList *list, GenericNode *node, u64 index, u64 item_size); GenericNode *_dbl_list_pop_back(GenericList *list, u64 item_size);
GenericNode *_dbl_list_pop_front(GenericList *list, u64 item_size); GenericNode *_dbl_list_remove(GenericList *list, u64 index, u64 item_size);
GenericNode *_dbl_list_pop_back(GenericList *list, u64 item_size); void _dbl_list_empty(GenericList *list, u64 item_size);
GenericNode *_dbl_list_remove(GenericList *list, u64 index, u64 item_size);
void _dbl_list_empty(GenericList *list, u64 item_size);
// Base list types
typedef struct str8 Str8;
WAPP_DEF_DBL_LIST_TYPE(void * , VoidPtrNode , VoidPtrList);
WAPP_DEF_DBL_LIST_TYPE(c8 , C8Node , C8List);
WAPP_DEF_DBL_LIST_TYPE(c16 , C16Node , C16List);
WAPP_DEF_DBL_LIST_TYPE(c32 , C32Node , C32List);
WAPP_DEF_DBL_LIST_TYPE(u8 , U8Node , U8List);
WAPP_DEF_DBL_LIST_TYPE(u16 , U16Node , U16List);
WAPP_DEF_DBL_LIST_TYPE(u32 , U32Node , U32List);
WAPP_DEF_DBL_LIST_TYPE(u64 , U64Node , U64List);
WAPP_DEF_DBL_LIST_TYPE(b8 , B8Node , B8List);
WAPP_DEF_DBL_LIST_TYPE(i8 , I8Node , I8List);
WAPP_DEF_DBL_LIST_TYPE(i16 , I16Node , I16List);
WAPP_DEF_DBL_LIST_TYPE(i32 , I32Node , I32List);
WAPP_DEF_DBL_LIST_TYPE(i64 , I64Node , I64List);
WAPP_DEF_DBL_LIST_TYPE(f32 , F32Node , F32List);
WAPP_DEF_DBL_LIST_TYPE(f64 , F64Node , F64List);
WAPP_DEF_DBL_LIST_TYPE(f128 , F128Node , F128List);
WAPP_DEF_DBL_LIST_TYPE(uptr , UptrNode , UptrList);
WAPP_DEF_DBL_LIST_TYPE(iptr , IptrNode , IptrList);
WAPP_DEF_DBL_LIST_TYPE(Str8 , Str8Node , Str8List);
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE

View File

@@ -21,7 +21,7 @@ void *wapp_mem_allocator_realloc(const Allocator *allocator, void *ptr, u64 old_
} }
void *wapp_mem_allocator_realloc_aligned(const Allocator *allocator, void *ptr, u64 old_size, void *wapp_mem_allocator_realloc_aligned(const Allocator *allocator, void *ptr, u64 old_size,
u64 new_size, u64 alignment) { u64 new_size, u64 alignment) {
wapp_debug_assert(allocator != NULL && (allocator->realloc_aligned) != NULL, "`allocator` and `allocator->realloc_aligned` should not be NULL"); 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); return allocator->realloc_aligned(ptr, old_size, new_size, alignment, allocator->obj);
} }

View File

@@ -11,14 +11,14 @@
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
typedef void *(MemAllocFunc)(u64 size, void *alloc_obj); typedef void *(MemAllocFunc)(u64 size, void *alloc_obj);
typedef void *(MemAllocAlignedFunc)(u64 size, u64 alignment, 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 *(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 *(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 void (MemFreeFunc)(void **ptr, u64 size, void *alloc_obj);
typedef struct allocator Allocator; typedef struct Allocator Allocator;
struct allocator { struct Allocator {
void *obj; void *obj;
MemAllocFunc *alloc; MemAllocFunc *alloc;
MemAllocAlignedFunc *alloc_aligned; MemAllocAlignedFunc *alloc_aligned;
@@ -28,9 +28,9 @@ struct allocator {
}; };
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
#define wapp_mem_allocator_invalid(ALLOCATOR) ([&]() { \ #define wapp_mem_allocator_invalid(ALLOCATOR) ([&]() { \
Allocator alloc{}; \ Allocator alloc{}; \
return memcmp(ALLOCATOR, &alloc, sizeof(Allocator)) == 0; \ return memcmp(ALLOCATOR, &alloc, sizeof(Allocator)) == 0; \
}()) }())
#else #else
#define wapp_mem_allocator_invalid(ALLOCATOR) (memcmp(ALLOCATOR, &((Allocator){0}), sizeof(Allocator)) == 0) #define wapp_mem_allocator_invalid(ALLOCATOR) (memcmp(ALLOCATOR, &((Allocator){0}), sizeof(Allocator)) == 0)
@@ -40,7 +40,7 @@ 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_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(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, void *wapp_mem_allocator_realloc_aligned(const Allocator *allocator, void *ptr, u64 old_size,
u64 new_size, u64 alignment); u64 new_size, u64 alignment);
void wapp_mem_allocator_free(const Allocator *allocator, void **ptr, u64 size); void wapp_mem_allocator_free(const Allocator *allocator, void **ptr, u64 size);
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP

View File

@@ -3,16 +3,15 @@
#include "mem_utils.h" #include "mem_utils.h"
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../../common/assert/assert.h" #include "../../../common/assert/assert.h"
#include "../../../common/misc/misc_utils.h"
#include <stddef.h> #include <stddef.h>
wapp_intern b8 is_power_of_two(u64 num) { return (num & (num - 1)) == 0; }
void *wapp_mem_util_align_forward(void *ptr, u64 alignment) { void *wapp_mem_util_align_forward(void *ptr, u64 alignment) {
wapp_debug_assert(ptr != NULL, "`ptr` should not be NULL"); 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"); wapp_runtime_assert(wapp_is_power_of_two(alignment), "`alignment` value is not a power of two");
uptr p = (uptr)ptr; uptr p = (uptr)ptr;
uptr align = (uptr)alignment; uptr align = (uptr)alignment;
// Similar to p % align, but it's a faster implementation that works fine // Similar to p % align, but it's a faster implementation that works fine
// because align is guaranteed to be a power of 2 // because align is guaranteed to be a power of 2

85
src/base/queue/queue.c Normal file
View File

@@ -0,0 +1,85 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "queue.h"
#include "../array/array.h"
#include "../../common/assert/assert.h"
#include "../../common/misc/misc_utils.h"
#include <string.h>
void _queue_push(GenericQueue *queue, void *item, u64 item_size) {
wapp_debug_assert(queue != NULL, "`queue` should not be NULL");
wapp_runtime_assert(item_size == wapp_array_item_size(queue->items), "Invalid type");
u64 capacity = wapp_array_capacity(queue->items);
if (queue->count >= capacity) { return; }
u64 index = (queue->back)++;
_array_set(queue->items, index, item, item_size);
++(queue->count);
if (queue->back >= capacity) {
queue->back = 0;
}
}
GenericQueue *_queue_push_alloc(const Allocator *allocator, GenericQueue *queue, void *item, u64 item_size) {
wapp_debug_assert(allocator != NULL && queue != NULL && item != NULL,
"`allocator`, `queue` and `item` should not be NULL");
wapp_runtime_assert(item_size == wapp_array_item_size(queue->items), "Invalid type");
GenericQueue *output = queue;
u64 capacity = wapp_array_capacity(queue->items);
if (queue->count >= capacity) {
u64 new_capacity = wapp_misc_utils_u64_round_up_pow2(capacity * 2);
u64 array_size = _array_calc_alloc_size(new_capacity, item_size);
u64 alloc_size = sizeof(GenericQueue) + array_size;
void *buffer = wapp_mem_allocator_alloc(allocator, alloc_size);
if (!buffer) {
goto RETURN_QUEUE_PUSH_ALLOC;
}
memset((void *)buffer, 0, alloc_size);
output = (GenericQueue *)buffer;
output->items = _array_from_preallocated_buffer((void *)(output + 1), array_size, ARRAY_INIT_FILLED, item_size);
// NOTE (Abdelrahman): When the queue is full, the front and back indices should
// always be the same
u64 front_count = capacity - queue->front;
u64 back_count = queue->back;
void *copy_boundary = (void *)((uptr)(queue->items) + (queue->front * item_size));
memcpy(output->items, copy_boundary, front_count * item_size);
if (back_count > 0) {
void *back_copy_dst = (void *)((uptr)(output->items) + (front_count * item_size));
memcpy(back_copy_dst, queue->items, back_count * item_size);
}
output->front = 0;
output->back = front_count + back_count;
output->count = queue->count;
}
_queue_push(output, item, item_size);
RETURN_QUEUE_PUSH_ALLOC:
return output;
}
void *_queue_pop(GenericQueue *queue, u64 item_size) {
wapp_debug_assert(queue != NULL, "`queue` should not be NULL");
wapp_runtime_assert(item_size == wapp_array_item_size(queue->items), "Invalid type");
if (queue->count == 0) { return NULL; }
u64 index = (queue->front)++;
--(queue->count);
u64 capacity = wapp_array_capacity(queue->items);
if (queue->front >= capacity) {
queue->front = 0;
}
return _array_get(queue->items, index, item_size);
}

100
src/base/queue/queue.h Normal file
View File

@@ -0,0 +1,100 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef QUEUE_H
#define QUEUE_H
#include "../array/array.h"
#include "../mem/allocator/mem_allocator.h"
#include "../../common/aliases/aliases.h"
#include "../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
typedef struct {
GenericArray items;
u64 front;
u64 back;
u64 count;
} GenericQueue;
// NOTE (Abdelrahman): GenericQueue typedefs for readability
typedef GenericQueue VoidPtrQueue;
typedef GenericQueue C8Queue;
typedef GenericQueue C16Queue;
typedef GenericQueue C32Queue;
typedef GenericQueue U8Queue;
typedef GenericQueue U16Queue;
typedef GenericQueue U32Queue;
typedef GenericQueue U64Queue;
typedef GenericQueue B8Queue;
typedef GenericQueue I8Queue;
typedef GenericQueue I16Queue;
typedef GenericQueue I32Queue;
typedef GenericQueue I64Queue;
typedef GenericQueue F32Queue;
typedef GenericQueue F64Queue;
typedef GenericQueue F128Queue;
typedef GenericQueue UptrQueue;
typedef GenericQueue IptrQueue;
typedef GenericQueue Str8Queue;
#ifdef WAPP_PLATFORM_CPP
#define wapp_queue(TYPE, CAPACITY) ([&]() { \
wapp_persist GenericArray arr = wapp_array_with_capacity(TYPE, CAPACITY, ARRAY_INIT_FILLED); \
wapp_persist GenericQueue queue = { \
arr, \
0, \
0, \
0, \
}; \
\
return queue; \
}())
#define wapp_queue_alloc(TYPE, ALLOCATOR_PTR, CAPACITY) ([&]() { \
wapp_persist GenericQueue queue = { \
wapp_array_alloc_capacity(TYPE, ALLOCATOR_PTR, CAPACITY, ARRAY_INIT_FILLED) \
0, \
0, \
0, \
}; \
\
return queue; \
}())
#else
#define wapp_queue(TYPE, CAPACITY) ((GenericQueue){ \
.items = wapp_array_with_capacity(TYPE, CAPACITY, ARRAY_INIT_FILLED), \
.front = 0, \
.back = 0, \
.count = 0, \
})
#define wapp_queue_alloc(TYPE, ALLOCATOR_PTR, CAPACITY) ((GenericQueue){ \
.items = wapp_array_alloc_capacity(TYPE, ALLOCATOR_PTR, CAPACITY, ARRAY_INIT_FILLED), \
.front = 0, \
.back = 0, \
.count = 0, \
})
#endif // !WAPP_PLATFORM_CPP
#define wapp_queue_capacity(QUEUE_PTR) (wapp_array_capacity((QUEUE_PTR)->items))
#define wapp_queue_item_size(QUEUE_PTR) (wapp_array_item_size((QUEUE_PTR)->items))
#define wapp_queue_push(TYPE, QUEUE_PTR, VALUE_PTR) ( \
_queue_push(QUEUE_PTR, VALUE_PTR, sizeof(TYPE)) \
)
#define wapp_queue_push_alloc(TYPE, ALLOCATOR_PTR, QUEUE_PTR, VALUE_PTR) ( \
_queue_push_alloc(ALLOCATOR_PTR, QUEUE_PTR, VALUE_PTR, sizeof(TYPE)) \
)
#define wapp_queue_pop(TYPE, QUEUE_PTR) ( \
(TYPE *)_queue_pop(QUEUE_PTR, sizeof(TYPE)) \
)
void _queue_push(GenericQueue *queue, void *item, u64 item_size);
GenericQueue *_queue_push_alloc(const Allocator *allocator, GenericQueue *queue, void *item, u64 item_size);
void *_queue_pop(GenericQueue *queue, u64 item_size);
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !QUEUE_H

View File

@@ -21,9 +21,9 @@ Str8 *wapp_str8_alloc_buf(const Allocator *allocator, u64 capacity) {
goto RETURN_STR8; goto RETURN_STR8;
} }
str->buf = (u8 *)str + sizeof(Str8); str->buf = (u8 *)str + sizeof(Str8);
str->size = 0; str->size = 0;
str->capacity = capacity; str->capacity = capacity;
RETURN_STR8: RETURN_STR8:
return str; return str;
@@ -41,8 +41,8 @@ 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_cstr(const Allocator *allocator, const char *str) {
wapp_debug_assert(allocator != NULL && str != NULL, "`allocator` and `str` should not be NULL"); wapp_debug_assert(allocator != NULL && str != NULL, "`allocator` and `str` should not be NULL");
u64 length = strlen(str); u64 length = strlen(str);
Str8 *output = wapp_str8_alloc_buf(allocator, length * 2); Str8 *output = wapp_str8_alloc_buf(allocator, length * 2);
if (!output) { if (!output) {
goto RETURN_ALLOC_CSTR; goto RETURN_ALLOC_CSTR;
} }
@@ -134,7 +134,7 @@ b8 wapp_str8_equal(Str8RO *s1, Str8RO *s2) {
b8 wapp_str8_equal_to_count(Str8RO* s1, Str8RO* s2, u64 count) { b8 wapp_str8_equal_to_count(Str8RO* s1, Str8RO* s2, u64 count) {
if (!s1 || !s2) { if (!s1 || !s2) {
return false; return false;
} }
return memcmp(s1->buf, s2->buf, count) == 0; return memcmp(s1->buf, s2->buf, count) == 0;
@@ -142,8 +142,8 @@ b8 wapp_str8_equal_to_count(Str8RO* s1, Str8RO* s2, u64 count) {
Str8 wapp_str8_slice(Str8RO *str, u64 start, u64 end) { Str8 wapp_str8_slice(Str8RO *str, u64 start, u64 end) {
if (start >= str->size || start >= end) { if (start >= str->size || start >= end) {
start = str->size; start = str->size;
end = str->size; end = str->size;
} }
if (end > str->size) { if (end > str->size) {
@@ -151,17 +151,17 @@ Str8 wapp_str8_slice(Str8RO *str, u64 start, u64 end) {
} }
return (Str8RO){ return (Str8RO){
.capacity = end - start, .capacity = end - start,
.size = end - start, .size = end - start,
.buf = str->buf + start, .buf = str->buf + start,
}; };
} }
Str8 *wapp_str8_alloc_concat(const Allocator *allocator, Str8 *dst, Str8RO *src) { 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"); wapp_debug_assert(allocator != NULL && dst != NULL && src != NULL, "`allocator`, `dst` and `src` should not be NULL");
Str8 *output = NULL; Str8 *output = NULL;
u64 remaining = dst->capacity - dst->size; u64 remaining = dst->capacity - dst->size;
if (src->size <= remaining) { if (src->size <= remaining) {
output = dst; output = dst;
goto SOURCE_STRING_STR8_CONCAT; goto SOURCE_STRING_STR8_CONCAT;
@@ -186,8 +186,8 @@ RETURN_STR8_CONCAT:
void wapp_str8_concat_capped(Str8 *dst, Str8RO *src) { void wapp_str8_concat_capped(Str8 *dst, Str8RO *src) {
wapp_debug_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL"); wapp_debug_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL");
u64 remaining = dst->capacity - dst->size; u64 remaining = dst->capacity - dst->size;
u64 to_copy = remaining < src->size ? remaining : src->size; u64 to_copy = remaining < src->size ? remaining : src->size;
memcpy(dst->buf + dst->size, src->buf, to_copy); memcpy(dst->buf + dst->size, src->buf, to_copy);
dst->size += to_copy; dst->size += to_copy;
@@ -196,8 +196,8 @@ void wapp_str8_concat_capped(Str8 *dst, Str8RO *src) {
void wapp_str8_copy_cstr_capped(Str8 *dst, const char *src) { 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"); wapp_debug_assert(dst != NULL && src != NULL, "`dst` and `src` should not be NULL");
u64 length = strlen(src); u64 length = strlen(src);
u64 to_copy = length <= dst->capacity ? length : dst->capacity; u64 to_copy = length <= dst->capacity ? length : dst->capacity;
memset(dst->buf, 0, dst->size); memset(dst->buf, 0, dst->size);
memcpy(dst->buf, src, to_copy); memcpy(dst->buf, src, to_copy);
@@ -232,8 +232,8 @@ void wapp_str8_format(Str8 *dst, const char *format, ...) {
va_start(args1, format); va_start(args1, format);
va_copy(args2, args1); va_copy(args2, args1);
u64 total_size = vsnprintf(NULL, 0, format, args1); u64 total_size = vsnprintf(NULL, 0, format, args1);
dst->size = total_size <= dst->capacity ? total_size : dst->capacity; dst->size = total_size <= dst->capacity ? total_size : dst->capacity;
vsnprintf((char *)(dst->buf), dst->capacity, format, args2); vsnprintf((char *)(dst->buf), dst->capacity, format, args2);
@@ -249,7 +249,7 @@ void wapp_str8_to_lower(Str8 *dst, Str8RO *src) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
wapp_str8_set(dst, index, (u8)tolower(wapp_str8_get(src, index))); wapp_str8_set(dst, index, (u8)tolower(wapp_str8_get(src, index)));
@@ -266,8 +266,8 @@ void wapp_str8_to_upper(Str8 *dst, Str8RO *src) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
wapp_str8_set(dst, index, (u8)toupper(wapp_str8_get(src, index))); wapp_str8_set(dst, index, (u8)toupper(wapp_str8_get(src, index)));
++index; ++index;
@@ -275,15 +275,15 @@ void wapp_str8_to_upper(Str8 *dst, Str8RO *src) {
} }
} }
void wapp_str8_from_bytes(Str8 *dst, const U8Array *src) { void wapp_str8_from_bytes(Str8 *dst, const U8Array src) {
wapp_debug_assert(src != NULL && dst != NULL, "`dst` and `src` should not be NULL"); wapp_debug_assert(src != NULL && dst != NULL, "`dst` and `src` should not be NULL");
u64 size = src->count * src->item_size; u64 size = wapp_array_count(src) * wapp_array_item_size(src);
wapp_debug_assert(dst->capacity >= size, "`dst` does not have enough capacity"); wapp_debug_assert(dst->capacity >= size, "`dst` does not have enough capacity");
dst->size = size; dst->size = size;
memcpy(dst->buf, src->items, size); memcpy(dst->buf, src, size);
} }
i64 wapp_str8_find(Str8RO *str, Str8RO substr) { i64 wapp_str8_find(Str8RO *str, Str8RO substr) {
@@ -293,8 +293,8 @@ i64 wapp_str8_find(Str8RO *str, Str8RO substr) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
u64 char_index = 0; u64 char_index = 0;
b8 running = char_index < str->size; b8 running = char_index < str->size;
while (running) { while (running) {
const c8 *sub = str->buf + char_index; const c8 *sub = str->buf + char_index;
if (memcmp(sub, substr.buf, substr.size) == 0) { if (memcmp(sub, substr.buf, substr.size) == 0) {
@@ -315,8 +315,8 @@ i64 wapp_str8_rfind(Str8RO *str, Str8RO substr) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
i64 char_index = str->size - substr.size; i64 char_index = str->size - substr.size;
b8 running = char_index >= 0; b8 running = char_index >= 0;
while (running) { while (running) {
const c8 *sub = str->buf + char_index; const c8 *sub = str->buf + char_index;
if (memcmp(sub, substr.buf, substr.size) == 0) { if (memcmp(sub, substr.buf, substr.size) == 0) {
@@ -333,23 +333,21 @@ i64 wapp_str8_rfind(Str8RO *str, Str8RO substr) {
Str8List *wapp_str8_split_with_max(const Allocator *allocator, Str8RO *str, Str8RO *delimiter, i64 max_splits) { 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"); wapp_debug_assert(allocator != NULL && str != NULL && delimiter != NULL, "`allocator`, `str` and `delimiter` should not be NULL");
Str8List *output = wapp_dbl_list_alloc(Str8, Str8List, allocator); Str8List *output = wapp_dbl_list_alloc(Str8, allocator);
if (delimiter->size > str->size) { if (delimiter->size > str->size) {
Str8 *full = wapp_str8_alloc_str8(allocator, str); Str8 *full = wapp_str8_alloc_str8(allocator, str);
Str8Node *node = wapp_dbl_list_node_alloc(Str8, Str8Node, allocator); if (full) {
if (node) { wapp_dbl_list_push_back_alloc(Str8, allocator, output, full);
node->item = full;
wapp_dbl_list_push_back(Str8, output, node);
} }
goto RETURN_STR8_SPLIT; goto RETURN_STR8_SPLIT;
} }
i64 start = 0; i64 start = 0;
i64 end = 0; i64 end = 0;
i64 splits = 0; i64 splits = 0;
Str8 *rest = wapp_str8_alloc_str8(allocator, str); Str8 *rest = wapp_str8_alloc_str8(allocator, str);
Str8 *before_str; Str8 *before_str;
while ((end = wapp_str8_find(rest, *delimiter)) != -1) { while ((end = wapp_str8_find(rest, *delimiter)) != -1) {
@@ -358,25 +356,21 @@ Str8List *wapp_str8_split_with_max(const Allocator *allocator, Str8RO *str, Str8
} }
before_str = wapp_str8_alloc_substr(allocator, str, start, start + end); before_str = wapp_str8_alloc_substr(allocator, str, start, start + end);
Str8Node *node = wapp_dbl_list_node_alloc(Str8, Str8Node, allocator); if (before_str) {
if (node && before_str) { wapp_dbl_list_push_back_alloc(Str8, allocator, output, before_str);
node->item = before_str;
wapp_dbl_list_push_back(Str8, output, node);
} }
wapp_mem_allocator_free(allocator, (void **)&rest, sizeof(Str8)); wapp_mem_allocator_free(allocator, (void **)&rest, sizeof(Str8));
rest = wapp_str8_alloc_substr(allocator, str, start + end + delimiter->size, str->size); rest = wapp_str8_alloc_substr(allocator, str, start + end + delimiter->size, str->size);
start += end + delimiter->size; start += end + delimiter->size;
++splits; ++splits;
} }
// Ensure the last part of the string after the delimiter is added to the list // 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); rest = wapp_str8_alloc_substr(allocator, str, start, str->size);
Str8Node *node = wapp_dbl_list_node_alloc(Str8, Str8Node, allocator); if (rest) {
if (node && rest) { wapp_dbl_list_push_back_alloc(Str8, allocator, output, rest);
node->item = rest;
wapp_dbl_list_push_back(Str8, output, node);
} }
RETURN_STR8_SPLIT: RETURN_STR8_SPLIT:
@@ -386,22 +380,20 @@ RETURN_STR8_SPLIT:
Str8List *wapp_str8_rsplit_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) {
wapp_debug_assert(allocator != NULL && str != NULL && delimiter != NULL, "`allocator`, `str` and `delimiter` should not be NULL"); wapp_debug_assert(allocator != NULL && str != NULL && delimiter != NULL, "`allocator`, `str` and `delimiter` should not be NULL");
Str8List *output = wapp_dbl_list_alloc(Str8, Str8List, allocator); Str8List *output = wapp_dbl_list_alloc(Str8, allocator);
if (delimiter->size > str->size) { if (delimiter->size > str->size) {
Str8 *full = wapp_str8_alloc_str8(allocator, str); Str8 *full = wapp_str8_alloc_str8(allocator, str);
Str8Node *node = wapp_dbl_list_node_alloc(Str8, Str8Node, allocator); if (full) {
if (node && full) { wapp_dbl_list_push_back_alloc(Str8, allocator, output, full);
node->item = full;
wapp_dbl_list_push_back(Str8, output, node);
} }
goto RETURN_STR8_SPLIT; goto RETURN_STR8_SPLIT;
} }
i64 end = 0; i64 end = 0;
i64 splits = 0; i64 splits = 0;
Str8 *rest = wapp_str8_alloc_str8(allocator, str); Str8 *rest = wapp_str8_alloc_str8(allocator, str);
Str8 *after_str; Str8 *after_str;
while ((end = wapp_str8_rfind(rest, *delimiter)) != -1) { while ((end = wapp_str8_rfind(rest, *delimiter)) != -1) {
@@ -410,10 +402,8 @@ Str8List *wapp_str8_rsplit_with_max(const Allocator *allocator, Str8RO *str, Str
} }
after_str = wapp_str8_alloc_substr(allocator, rest, end + delimiter->size, str->size); after_str = wapp_str8_alloc_substr(allocator, rest, end + delimiter->size, str->size);
Str8Node *node = wapp_dbl_list_node_alloc(Str8, Str8Node, allocator); if (after_str) {
if (node) { wapp_dbl_list_push_front_alloc(Str8, allocator, output, after_str);
node->item = after_str;
wapp_dbl_list_push_front(Str8, output, node);
} }
wapp_mem_allocator_free(allocator, (void **)&rest, sizeof(Str8)); wapp_mem_allocator_free(allocator, (void **)&rest, sizeof(Str8));
@@ -422,11 +412,9 @@ Str8List *wapp_str8_rsplit_with_max(const Allocator *allocator, Str8RO *str, Str
++splits; ++splits;
} }
rest = wapp_str8_alloc_substr(allocator, str, 0, rest->size); rest = wapp_str8_alloc_substr(allocator, str, 0, rest->size);
Str8Node *node = wapp_dbl_list_node_alloc(Str8, Str8Node, allocator); if (rest) {
if (node && rest) { wapp_dbl_list_push_front_alloc(Str8, allocator, output, rest);
node->item = rest;
wapp_dbl_list_push_front(Str8, output, node);
} }
RETURN_STR8_SPLIT: RETURN_STR8_SPLIT:
@@ -441,16 +429,16 @@ Str8 *wapp_str8_join(const Allocator *allocator, const Str8List *list, Str8RO *d
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
Str8Node *node; Str8 *node;
u64 node_index = 0; u64 node_index = 0;
b8 running = node_index < list->node_count; b8 running = node_index < list->node_count;
while (running) { while (running) {
node = wapp_dbl_list_get(Str8, Str8Node, list, node_index); node = wapp_dbl_list_get(Str8, list, node_index);
if (!node) { if (!node) {
break; break;
} }
wapp_str8_concat_capped(output, node->item); wapp_str8_concat_capped(output, node);
// NOTE (Abdelrahman): Comparison extracted to variable to silence // NOTE (Abdelrahman): Comparison extracted to variable to silence
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
@@ -473,17 +461,17 @@ u64 wapp_str8_list_total_size(const Str8List *list) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
Str8Node* node; Str8 *node;
u64 node_index = 0; u64 node_index = 0;
u64 output = 0; u64 output = 0;
b8 running = node_index < list->node_count; b8 running = node_index < list->node_count;
while (running) { while (running) {
node = wapp_dbl_list_get(Str8, Str8Node, list, node_index); node = wapp_dbl_list_get(Str8, list, node_index);
if (!node) { if (!node) {
break; break;
} }
output += node->item->size; output += node->size;
++node_index; ++node_index;
running = node_index < list->node_count; running = node_index < list->node_count;
} }

View File

@@ -15,8 +15,8 @@
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
typedef struct str8 Str8; typedef struct Str8 Str8;
struct str8 { struct Str8 {
u64 capacity; u64 capacity;
u64 size; u64 size;
c8 *buf; c8 *buf;
@@ -36,17 +36,17 @@ typedef const Str8 Str8RO;
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
// Uses a lambda to achieve the same behaviour achieved by the C macro // Uses a lambda to achieve the same behaviour achieved by the C macro
#define wapp_str8_buf(CAPACITY) ([&](){ \ #define wapp_str8_buf(CAPACITY) ([&](){ \
wapp_persist c8 buf[CAPACITY] = {}; \ wapp_persist c8 buf[CAPACITY] = {}; \
memset(buf, 0, CAPACITY); \ memset(buf, 0, CAPACITY); \
return Str8{CAPACITY, 0, buf}; \ return Str8{CAPACITY, 0, buf}; \
}()) }())
// Uses a lambda to achieve the same behaviour achieved by the C macro // Uses a lambda to achieve the same behaviour achieved by the C macro
#define wapp_str8_lit(STRING) ([&]() { \ #define wapp_str8_lit(STRING) ([&]() { \
wapp_persist c8 buf[sizeof(STRING) * 2] = {}; \ wapp_persist c8 buf[sizeof(STRING) * 2] = {}; \
memcpy(buf, STRING, sizeof(STRING)); \ memcpy(buf, STRING, sizeof(STRING)); \
return Str8{(sizeof(STRING) - 1) * 2, sizeof(STRING) - 1, buf}; \ 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(STRING) Str8RO{sizeof(STRING) - 1, sizeof(STRING) - 1, (c8 *)STRING}
@@ -56,29 +56,31 @@ typedef const Str8 Str8RO;
// Utilises the fact that memcpy returns pointer to dest buffer and that getting // 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 // 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, \ #define wapp_str8_lit(STRING) ((Str8){.capacity = (sizeof(STRING) - 1) * 2, \
.size = sizeof(STRING) - 1, \ .size = sizeof(STRING) - 1, \
.buf = memcpy(&((c8 [sizeof(STRING) * 2]){0}), STRING, sizeof(STRING))}) .buf = memcpy(&((c8 [sizeof(STRING) * 2]){0}), \
#define wapp_str8_lit_ro(STRING) ((Str8RO){.capacity = sizeof(STRING) - 1, \ STRING, \
.size = sizeof(STRING) - 1, \ sizeof(STRING))})
.buf = (c8 *)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 // 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 // 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 // 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, \ #define wapp_str8_lit_ro_initialiser_list(STRING) {.capacity = sizeof(STRING) - 1, \
.size = sizeof(STRING) - 1, \ .size = sizeof(STRING) - 1, \
.buf = (c8 *)STRING} .buf = (c8 *)STRING}
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
/** /**
* Str8 allocated buffers * Str8 allocated buffers
*/ */
Str8 *wapp_str8_alloc_buf(const Allocator *allocator, u64 capacity); 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_and_fill_buf(const Allocator *allocator, u64 capacity);
Str8 *wapp_str8_alloc_cstr(const Allocator *allocator, const char *str); 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_str8(const Allocator *allocator, Str8RO *str);
Str8 *wapp_str8_alloc_substr(const Allocator *allocator, Str8RO *str, u64 start, u64 end); 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); 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. // 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. // No need to use it for allocators like Arena.
void wapp_str8_dealloc_buf(const Allocator *allocator, Str8 **str); void wapp_str8_dealloc_buf(const Allocator *allocator, Str8 **str);
@@ -86,20 +88,20 @@ void wapp_str8_dealloc_buf(const Allocator *allocator, Str8 **str);
/** /**
* Str8 utilities * Str8 utilities
*/ */
c8 wapp_str8_get(Str8RO *str, u64 index); c8 wapp_str8_get(Str8RO *str, u64 index);
void wapp_str8_set(Str8 *str, u64 index, c8 c); void wapp_str8_set(Str8 *str, u64 index, c8 c);
void wapp_str8_push_back(Str8 *str, c8 c); void wapp_str8_push_back(Str8 *str, c8 c);
b8 wapp_str8_equal(Str8RO *s1, Str8RO *s2); b8 wapp_str8_equal(Str8RO *s1, Str8RO *s2);
b8 wapp_str8_equal_to_count(Str8RO* s1, Str8RO* s2, u64 count); b8 wapp_str8_equal_to_count(Str8RO* s1, Str8RO* s2, u64 count);
Str8 wapp_str8_slice(Str8RO *str, u64 start, u64 end); Str8 wapp_str8_slice(Str8RO *str, u64 start, u64 end);
void wapp_str8_concat_capped(Str8 *dst, Str8RO *src); void wapp_str8_concat_capped(Str8 *dst, Str8RO *src);
void wapp_str8_copy_cstr_capped(Str8 *dst, const char *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_str8_capped(Str8 *dst, Str8RO *src);
void wapp_str8_copy_to_cstr(char *dst, Str8RO *src, u64 dst_capacity); void wapp_str8_copy_to_cstr(char *dst, Str8RO *src, u64 dst_capacity);
void wapp_str8_format(Str8 *dst, const char *format, ...); void wapp_str8_format(Str8 *dst, const char *format, ...);
void wapp_str8_to_lower(Str8 *dst, Str8RO *src); void wapp_str8_to_lower(Str8 *dst, Str8RO *src);
void wapp_str8_to_upper(Str8 *dst, Str8RO *src); void wapp_str8_to_upper(Str8 *dst, Str8RO *src);
void wapp_str8_from_bytes(Str8 *dst, const U8Array *src); void wapp_str8_from_bytes(Str8 *dst, const U8Array src);
/** /**
* Str8 find functions * Str8 find functions
@@ -112,9 +114,9 @@ i64 wapp_str8_rfind(Str8RO *str, Str8RO substr);
*/ */
#define wapp_str8_split(ALLOCATOR, STR, DELIMITER) wapp_str8_split_with_max(ALLOCATOR, STR, DELIMITER, -1) #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) #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_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); 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 *wapp_str8_join(const Allocator *allocator, const Str8List *list, Str8RO *delimiter);
/** /**
* Str8 list utilities * Str8 list utilities
@@ -123,27 +125,6 @@ u64 wapp_str8_list_total_size(const Str8List *list);
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE
#include <type_traits>
template <typename T>
constexpr bool is_lvalue(T&&) {
return std::is_lvalue_reference<T>{};
}
#define wapp_str8_node_from_cstr(STRING) wapp_dbl_list_node(Str8, Str8Node, [&]() { \
wapp_persist Str8 str = wapp_str8_lit(STRING); \
return &str; \
}())
#define wapp_str8_node_from_str8(STRING) wapp_dbl_list_node(Str8, Str8Node, [&]() { \
if (is_lvalue(STRING)) { return &STRING; } \
\
wapp_persist Str8 str = STRING; \
return &str; \
}())
#else
#define wapp_str8_node_from_cstr(STRING) wapp_dbl_list_node(Str8, Str8Node, &wapp_str8_lit(STRING))
#define wapp_str8_node_from_str8(STRING) wapp_dbl_list_node(Str8, Str8Node, &(STRING))
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
#endif // !STR8_H #endif // !STR8_H

View File

@@ -6,6 +6,7 @@
#include "wapp_base.h" #include "wapp_base.h"
#include "array/array.c" #include "array/array.c"
#include "dbl_list/dbl_list.c" #include "dbl_list/dbl_list.c"
#include "queue/queue.c"
#include "mem/allocator/mem_allocator.c" #include "mem/allocator/mem_allocator.c"
#include "mem/utils/mem_utils.c" #include "mem/utils/mem_utils.c"
#include "strings/str8/str8.c" #include "strings/str8/str8.c"

View File

@@ -3,8 +3,9 @@
#ifndef WAPP_BASE_H #ifndef WAPP_BASE_H
#define WAPP_BASE_H #define WAPP_BASE_H
#include "dbl_list/dbl_list.h"
#include "array/array.h" #include "array/array.h"
#include "dbl_list/dbl_list.h"
#include "queue/queue.h"
#include "mem/allocator/mem_allocator.h" #include "mem/allocator/mem_allocator.h"
#include "mem/utils/mem_utils.h" #include "mem/utils/mem_utils.h"
#include "strings/str8/str8.h" #include "strings/str8/str8.h"

View File

@@ -10,25 +10,25 @@
#include <uchar.h> #include <uchar.h>
#if WAPP_PLATFORM_C_VERSION >= WAPP_PLATFORM_C23_VERSION #if WAPP_PLATFORM_C_VERSION >= WAPP_PLATFORM_C23_VERSION
#define c8 char8_t typedef char8_t c8;
#else #else
#define c8 uint8_t typedef uint8_t c8;
#endif // !WAPP_PLATFORM_C23_VERSION #endif // !WAPP_PLATFORM_C23_VERSION
#define c16 char16_t typedef char16_t c16;
#define c32 char32_t typedef char32_t c32;
#else #else
#define c8 uint8_t typedef uint8_t c8;
#define c16 uint16_t typedef uint16_t c16;
#define c32 uint32_t typedef uint32_t c32;
#endif // !WAPP_PLATFORM_C #endif // !WAPP_PLATFORM_C
#define u8 uint8_t typedef uint8_t u8;
#define u16 uint16_t typedef uint16_t u16;
#define u32 uint32_t typedef uint32_t u32;
#define u64 uint64_t typedef uint64_t u64;
#define b8 uint8_t typedef uint8_t b8;
#ifndef WAPP_PLATFORM_CPP #ifndef WAPP_PLATFORM_CPP
@@ -42,17 +42,17 @@
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
#define i8 int8_t typedef int8_t i8;
#define i16 int16_t typedef int16_t i16;
#define i32 int32_t typedef int32_t i32;
#define i64 int64_t typedef int64_t i64;
#define f32 float typedef float f32;
#define f64 double typedef double f64;
#define f128 long double typedef long double f128;
#define uptr uintptr_t typedef uintptr_t uptr;
#define iptr intptr_t typedef intptr_t iptr;
#define wapp_extern extern #define wapp_extern extern
#define wapp_intern static #define wapp_intern static

View File

@@ -28,30 +28,30 @@ BEGIN_C_LINKAGE
#endif #endif
#ifdef WAPP_PLATFORM_WINDOWS #ifdef WAPP_PLATFORM_WINDOWS
#define __wapp_runtime_assert(EXPR, MSG) do { \ #define __wapp_runtime_assert(EXPR, MSG) do { \
__pragma(warning(push)) \ __pragma(warning(push)) \
__pragma(warning(disable:4127)) \ __pragma(warning(disable:4127)) \
if (!(EXPR)) { \ if (!(EXPR)) { \
__pragma(warning(pop)) \ __pragma(warning(pop)) \
__runtime_assert_failed(EXPR, MSG); \ __runtime_assert_failed(EXPR, MSG); \
} \ } \
} while(false) } while(false)
#else #else
#define __wapp_runtime_assert(EXPR, MSG) do { \ #define __wapp_runtime_assert(EXPR, MSG) do { \
if (!(EXPR)) { \ if (!(EXPR)) { \
__runtime_assert_failed(EXPR, MSG); \ __runtime_assert_failed(EXPR, MSG); \
} \ } \
} while(false) } while(false)
#endif // !WAPP_PLATFORM_WINDOWS #endif // !WAPP_PLATFORM_WINDOWS
#define __runtime_assert_failed(EXPR, MSG) do { \ #define __runtime_assert_failed(EXPR, MSG) do { \
fprintf( \ fprintf( \
stderr, \ stderr, \
"%s:%d (In function `%s`): Assertion failed (%" PRIu32 ")\nDiagnostic: %s\n\n", \ "%s:%d (In function `%s`): Assertion failed (%" PRIu32 ")\nDiagnostic: %s\n\n", \
__FILE__, __LINE__, __func__, \ __FILE__, __LINE__, __func__, \
EXPR, MSG \ EXPR, MSG \
); \ ); \
abort(); \ abort(); \
} while(false) } while(false)
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP

View File

@@ -16,37 +16,40 @@ BEGIN_C_LINKAGE
#define PiB(SIZE) (((u64)SIZE) << 50) #define PiB(SIZE) (((u64)SIZE) << 50)
#define EiB(SIZE) (((u64)SIZE) << 60) #define EiB(SIZE) (((u64)SIZE) << 60)
#define KB(SIZE) (((u64)SIZE) * 1000llu) #define KB(SIZE) (((u64)SIZE) * 1000llu)
#define MB(SIZE) (KB(SIZE) * 1000llu) #define MB(SIZE) (KB(SIZE) * 1000llu)
#define GB(SIZE) (MB(SIZE) * 1000llu) #define GB(SIZE) (MB(SIZE) * 1000llu)
#define TB(SIZE) (GB(SIZE) * 1000llu) #define TB(SIZE) (GB(SIZE) * 1000llu)
#define PB(SIZE) (TB(SIZE) * 1000llu) #define PB(SIZE) (TB(SIZE) * 1000llu)
#define EB(SIZE) (PB(SIZE) * 1000llu) #define EB(SIZE) (PB(SIZE) * 1000llu)
#define wapp_misc_utils_padding_size(SIZE) u8 reserved_padding[sizeof(void *) - ((SIZE) % sizeof(void *))] #define wapp_misc_utils_reserve_padding(SIZE) u8 reserved_padding[sizeof(void *) - ((SIZE) % sizeof(void *))]
#define U64_RSHIFT_OR_1(X) (((u64)X) | (((u64)X) >> 1)) #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_2(X) (((u64)X) | (((u64)X) >> 2))
#define U64_RSHIFT_OR_4(X) (((u64)X) | (((u64)X) >> 4)) #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_8(X) (((u64)X) | (((u64)X) >> 8))
#define U64_RSHIFT_OR_16(X) (((u64)X) | (((u64)X) >> 16)) #define U64_RSHIFT_OR_16(X) (((u64)X) | (((u64)X) >> 16))
#define U64_RSHIFT_OR_32(X) (((u64)X) | (((u64)X) >> 32)) #define U64_RSHIFT_OR_32(X) (((u64)X) | (((u64)X) >> 32))
#define wapp_misc_utils_u64_round_up_pow2(X) ( \ #define wapp_misc_utils_u64_round_up_pow2(X) ( \
( \ ( \
U64_RSHIFT_OR_32( \ U64_RSHIFT_OR_32( \
U64_RSHIFT_OR_16( \ U64_RSHIFT_OR_16( \
U64_RSHIFT_OR_8( \ U64_RSHIFT_OR_8( \
U64_RSHIFT_OR_4( \ U64_RSHIFT_OR_4( \
U64_RSHIFT_OR_2( \ U64_RSHIFT_OR_2( \
U64_RSHIFT_OR_1(X - 1) \ U64_RSHIFT_OR_1(X - 1) \
) \ ) \
) \ ) \
) \ ) \
) \ ) \
) \ ) \
) + 1 \ ) + 1 \
) )
#define wapp_is_power_of_two(NUM) ((NUM & (NUM - 1)) == 0)
#define wapp_pointer_offset(PTR, OFFSET) ((void *)((uptr)(PTR) + (OFFSET)))
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE

View File

@@ -6,7 +6,6 @@
#include "../../../common/assert/assert.h" #include "../../../common/assert/assert.h"
#include "../../../common/misc/misc_utils.h" #include "../../../common/misc/misc_utils.h"
#include "../../../base/mem/utils/mem_utils.h" #include "../../../base/mem/utils/mem_utils.h"
#include <stdlib.h>
#include <string.h> #include <string.h>
#ifndef DEFAULT_ALIGNMENT #ifndef DEFAULT_ALIGNMENT
@@ -17,45 +16,70 @@
#define ARENA_MINIMUM_CAPACITY KiB(16) // Allocate minimum of 4 pages #define ARENA_MINIMUM_CAPACITY KiB(16) // Allocate minimum of 4 pages
struct arena { typedef enum {
ARENA_STORAGE_TYPE_ALLOCATED,
ARENA_STORAGE_TYPE_BUFFER,
} ArenaStorageType;
struct Arena {
u8 *buf; u8 *buf;
u8 *offset; u8 *offset;
u8 *prev_offset;
u64 capacity; u64 capacity;
ArenaStorageType type;
b8 committed; b8 committed;
#ifdef WAPP_PLATFORM_WINDOWS wapp_misc_utils_reserve_padding(sizeof(u8 *) * 3 + sizeof(u64) + sizeof(ArenaStorageType) + sizeof(b8));
wapp_misc_utils_padding_size(sizeof(u8 *) * 2 + sizeof(u64) + sizeof(b8));
#endif // ifdef WAPP_PLATFORM_WINDOWS
}; };
b8 wapp_mem_arena_init_custom(Arena **arena, u64 base_capacity, MemAllocFlags flags, b8 zero_buffer) { b8 wapp_mem_arena_init_buffer(Arena **arena, u8 *buffer, u64 buffer_size) {
if (!arena || *arena || buffer_size < sizeof(Arena)) {
return false;
}
*arena = (Arena *)buffer;
Arena *arena_ptr = *arena;
arena_ptr->buf = (u8 *)(arena_ptr + 1);
arena_ptr->offset = arena_ptr->buf;
arena_ptr->prev_offset = NULL;
arena_ptr->capacity = buffer_size - sizeof(Arena);
arena_ptr->type = ARENA_STORAGE_TYPE_BUFFER;
arena_ptr->committed = true;
return true;
}
b8 wapp_mem_arena_init_allocated_custom(Arena **arena, u64 base_capacity, MemAllocFlags flags, b8 zero_buffer) {
if (!arena || *arena || base_capacity == 0) { if (!arena || *arena || base_capacity == 0) {
return false; return false;
} }
*arena = (Arena *)calloc(1, sizeof(Arena)); u64 size = sizeof(Arena) + (base_capacity >= ARENA_MINIMUM_CAPACITY ? base_capacity : ARENA_MINIMUM_CAPACITY);
Arena *arena_ptr = *arena; u64 alloc_size = wapp_misc_utils_u64_round_up_pow2(size);
if (!arena_ptr) { u8 *allocated = (u8 *)wapp_os_mem_alloc(NULL, alloc_size, WAPP_MEM_ACCESS_READ_WRITE, flags,
zero_buffer ? WAPP_MEM_INIT_INITIALISED : WAPP_MEM_INIT_UNINITIALISED);
if (!allocated) {
return false; return false;
} }
u64 arena_capacity = wapp_misc_utils_u64_round_up_pow2( b8 committed = (flags & WAPP_MEM_ALLOC_COMMIT) == WAPP_MEM_ALLOC_COMMIT;
base_capacity >= ARENA_MINIMUM_CAPACITY ?
base_capacity :
ARENA_MINIMUM_CAPACITY
);
arena_ptr->buf = (u8 *)wapp_os_mem_alloc(NULL, arena_capacity, WAPP_MEM_ACCESS_READ_WRITE, flags, #ifdef WAPP_PLATFORM_WINDOWS
zero_buffer ? WAPP_MEM_INIT_INITIALISED : WAPP_MEM_INIT_UNINITIALISED); if (!committed) {
wapp_os_mem_alloc(allocated, sizeof(Arena), WAPP_MEM_ACCESS_READ_WRITE, WAPP_MEM_ALLOC_COMMIT,
WAPP_MEM_INIT_INITIALISED);
}
#endif // ifdef WAPP_PLATFORM_WINDOWS
if (!(arena_ptr->buf)) { if (!wapp_mem_arena_init_buffer(arena, allocated, alloc_size)) {
wapp_mem_arena_destroy(arena); wapp_mem_arena_destroy(arena);
return false; return false;
} }
arena_ptr->capacity = arena_capacity; Arena *arena_ptr = *arena;
arena_ptr->offset = arena_ptr->buf; arena_ptr->type = ARENA_STORAGE_TYPE_ALLOCATED;
arena_ptr->committed = (flags & WAPP_MEM_ALLOC_COMMIT) == WAPP_MEM_ALLOC_COMMIT; arena_ptr->committed = committed;
return true; return true;
} }
@@ -77,10 +101,10 @@ void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment) {
arena->offset = output + size; arena->offset = output + size;
#ifdef WAPP_PLATFORM_WINDOWS #ifdef WAPP_PLATFORM_WINDOWS
if (!(arena->committed)) { if (arena->type == ARENA_STORAGE_TYPE_ALLOCATED && !(arena->committed)) {
wapp_os_mem_alloc(alloc_start, (uptr)(arena->offset) - (uptr)(alloc_start), wapp_os_mem_alloc(alloc_start, (uptr)(arena->offset) - (uptr)(alloc_start),
WAPP_MEM_ACCESS_READ_WRITE, WAPP_MEM_ALLOC_COMMIT, WAPP_MEM_ACCESS_READ_WRITE, WAPP_MEM_ALLOC_COMMIT,
WAPP_MEM_INIT_UNINITIALISED); WAPP_MEM_INIT_UNINITIALISED);
} }
#endif // ifdef WAPP_PLATFORM_WINDOWS #endif // ifdef WAPP_PLATFORM_WINDOWS
@@ -90,8 +114,10 @@ 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(Arena *arena, void *ptr, u64 old_size, u64 new_size) {
wapp_debug_assert(arena != NULL, "`arena` should not be NULL");
if ((u8*)ptr < arena->buf || (u8*)ptr > arena->offset || if ((u8*)ptr < arena->buf || (u8*)ptr > arena->offset ||
arena->offset + new_size >= arena->buf + arena->capacity) { arena->offset + new_size >= arena->buf + arena->capacity) {
return NULL; return NULL;
} }
@@ -107,8 +133,10 @@ 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_realloc_aligned(Arena *arena, void *ptr, u64 old_size, u64 new_size, u64 alignment) {
wapp_debug_assert(arena != NULL, "`arena` should not be NULL");
if ((u8*)ptr < arena->buf || (u8*)ptr > arena->offset || if ((u8*)ptr < arena->buf || (u8*)ptr > arena->offset ||
arena->offset + new_size >= arena->buf + arena->capacity) { arena->offset + new_size >= arena->buf + arena->capacity) {
return NULL; return NULL;
} }
@@ -123,6 +151,27 @@ void *wapp_mem_arena_realloc_aligned(Arena *arena, void *ptr, u64 old_size, u64
return new_ptr; return new_ptr;
} }
void wapp_mem_arena_temp_begin(Arena *arena) {
wapp_debug_assert(arena != NULL, "`arena` should not be NULL");
if (arena->prev_offset != NULL) {
return;
}
arena->prev_offset = arena->offset;
}
void wapp_mem_arena_temp_end(Arena *arena) {
wapp_debug_assert(arena != NULL, "`arena` should not be NULL");
if (arena->prev_offset == NULL) {
return;
}
arena->offset = arena->prev_offset;
arena->prev_offset = NULL;
}
void wapp_mem_arena_clear(Arena *arena) { void wapp_mem_arena_clear(Arena *arena) {
wapp_debug_assert(arena != NULL, "`arena` should not be NULL"); wapp_debug_assert(arena != NULL, "`arena` should not be NULL");
@@ -134,13 +183,10 @@ void wapp_mem_arena_destroy(Arena **arena) {
wapp_debug_assert(arena != NULL && (*arena) != NULL, "`arena` double pointer is not valid"); wapp_debug_assert(arena != NULL && (*arena) != NULL, "`arena` double pointer is not valid");
Arena *arena_ptr = *arena; Arena *arena_ptr = *arena;
if (arena_ptr->buf) {
wapp_os_mem_free(arena_ptr->buf, arena_ptr->capacity); if (arena_ptr->type == ARENA_STORAGE_TYPE_ALLOCATED) {
wapp_os_mem_free(*arena, sizeof(Arena) + arena_ptr->capacity);
} }
arena_ptr->buf = arena_ptr->offset = NULL;
arena_ptr->capacity = 0;
free(*arena);
*arena = NULL; *arena = NULL;
} }

View File

@@ -11,29 +11,32 @@
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
typedef struct arena Arena; typedef struct Arena Arena;
#define wapp_mem_arena_init(arena_dptr, base_capacity) \ #define wapp_mem_arena_init_allocated(arena_dptr, base_capacity) \
(wapp_mem_arena_init_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE, false)) (wapp_mem_arena_init_allocated_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE, false))
#define wapp_mem_arena_init_commit(arena_dptr, base_capacity) \ #define wapp_mem_arena_init_allocated_commit(arena_dptr, base_capacity) \
(wapp_mem_arena_init_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE | WAPP_MEM_ALLOC_COMMIT, false)) (wapp_mem_arena_init_allocated_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE | WAPP_MEM_ALLOC_COMMIT, false))
#define wapp_mem_arena_init_zero(arena_dptr, base_capacity) \ #define wapp_mem_arena_init_allocated_zero(arena_dptr, base_capacity) \
(wapp_mem_arena_init_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE, true)) (wapp_mem_arena_init_allocated_custom(arena_dptr, base_capacity, WAPP_MEM_ALLOC_RESERVE, true))
#define wapp_mem_arena_init_commit_and_zero(arena_dptr, base_capacity) \ #define wapp_mem_arena_init_allocated_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)) (wapp_mem_arena_init_allocated_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 * Arena initialisation function. `wapp_mem_arena_init_allocated_custom` provides the most
* control over how the Arena is initialised. Wrapper macros are provided for * control over how the Arena is initialised. Wrapper macros are provided for
* easier use. * easier use.
*/ */
b8 wapp_mem_arena_init_custom(Arena **arena, u64 base_capacity, MemAllocFlags flags, b8 zero_buffer); b8 wapp_mem_arena_init_allocated_custom(Arena **arena, u64 base_capacity, MemAllocFlags flags, b8 zero_buffer);
void *wapp_mem_arena_alloc(Arena *arena, u64 size); b8 wapp_mem_arena_init_buffer(Arena **arena, u8 *buffer, u64 buffer_size);
void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment); void *wapp_mem_arena_alloc(Arena *arena, u64 size);
void *wapp_mem_arena_realloc(Arena *arena, void *ptr, u64 old_size, u64 new_size); void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment);
void *wapp_mem_arena_realloc_aligned(Arena *arena, void *ptr, u64 old_size, u64 new_size, u64 alignment); void *wapp_mem_arena_realloc(Arena *arena, void *ptr, u64 old_size, u64 new_size);
void wapp_mem_arena_clear(Arena *arena); void *wapp_mem_arena_realloc_aligned(Arena *arena, void *ptr, u64 old_size, u64 new_size, u64 alignment);
void wapp_mem_arena_destroy(Arena **arena); void wapp_mem_arena_temp_begin(Arena *arena);
void wapp_mem_arena_temp_end(Arena *arena);
void wapp_mem_arena_clear(Arena *arena);
void wapp_mem_arena_destroy(Arena **arena);
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE

View File

@@ -4,38 +4,66 @@
#include "mem_arena.h" #include "mem_arena.h"
#include "../../mem/mem_os.h" #include "../../mem/mem_os.h"
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../../common/assert/assert.h"
wapp_intern void initialise_arena_allocator(Allocator *allocator);
wapp_intern void *mem_arena_alloc(u64 size, void *alloc_obj); wapp_intern void *mem_arena_alloc(u64 size, void *alloc_obj);
wapp_intern void *mem_arena_alloc_aligned(u64 size, u64 alignment, void *alloc_obj); wapp_intern void *mem_arena_alloc_aligned(u64 size, u64 alignment, void *alloc_obj);
wapp_intern void *mem_arena_realloc(void *ptr, u64 old_size, u64 new_size, void *alloc_obj); wapp_intern void *mem_arena_realloc(void *ptr, u64 old_size, u64 new_size, void *alloc_obj);
wapp_intern void *mem_arena_realloc_aligned(void *ptr, u64 old_size, u64 new_size, u64 alignment, wapp_intern void *mem_arena_realloc_aligned(void *ptr, u64 old_size, u64 new_size, u64 alignment,
void *alloc_obj); void *alloc_obj);
Allocator wapp_mem_arena_allocator_init_with_buffer(u8 *buffer, u64 buffer_size) {
Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags flags, b8 zero_buffer) {
Allocator allocator = {0}; Allocator allocator = {0};
b8 initialised = wapp_mem_arena_init_custom((Arena **)(&allocator.obj), base_capacity, flags, zero_buffer); b8 initialised = wapp_mem_arena_init_buffer((Arena **)(&allocator.obj), buffer, buffer_size);
if (!initialised) { if (!initialised) {
return allocator; return allocator;
} }
allocator.alloc = mem_arena_alloc; initialise_arena_allocator(&allocator);
allocator.alloc_aligned = mem_arena_alloc_aligned;
allocator.realloc = mem_arena_realloc;
allocator.realloc_aligned = mem_arena_realloc_aligned;
return allocator; return allocator;
} }
Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags flags, b8 zero_buffer) {
Allocator allocator = {0};
b8 initialised = wapp_mem_arena_init_allocated_custom((Arena **)(&allocator.obj), base_capacity, flags, zero_buffer);
if (!initialised) {
return allocator;
}
initialise_arena_allocator(&allocator);
return allocator;
}
void wapp_mem_arena_allocator_temp_begin(const Allocator *allocator) {
wapp_debug_assert(allocator != NULL, "`allocator` should not be NULL");
wapp_mem_arena_temp_begin((Arena *)(allocator->obj));
}
void wapp_mem_arena_allocator_temp_end(const Allocator *allocator) {
wapp_debug_assert(allocator != NULL, "`allocator` should not be NULL");
wapp_mem_arena_temp_end((Arena *)(allocator->obj));
}
void wapp_mem_arena_allocator_clear(Allocator *allocator) { void wapp_mem_arena_allocator_clear(Allocator *allocator) {
wapp_debug_assert(allocator != NULL, "`allocator` should not be NULL");
wapp_mem_arena_clear((Arena *)(allocator->obj)); wapp_mem_arena_clear((Arena *)(allocator->obj));
} }
void wapp_mem_arena_allocator_destroy(Allocator *allocator) { void wapp_mem_arena_allocator_destroy(Allocator *allocator) {
wapp_debug_assert(allocator != NULL, "`allocator` should not be NULL");
wapp_mem_arena_destroy((Arena **)(&(allocator->obj))); wapp_mem_arena_destroy((Arena **)(&(allocator->obj)));
*allocator = (Allocator){0}; *allocator = (Allocator){0};
} }
wapp_intern void initialise_arena_allocator(Allocator *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;
}
wapp_intern void *mem_arena_alloc(u64 size, void *alloc_obj) { wapp_intern void *mem_arena_alloc(u64 size, void *alloc_obj) {
Arena *arena = (Arena *)alloc_obj; Arena *arena = (Arena *)alloc_obj;
@@ -53,7 +81,7 @@ wapp_intern void *mem_arena_realloc(void *ptr, u64 old_size, u64 new_size, void
} }
wapp_intern void *mem_arena_realloc_aligned(void *ptr, u64 old_size, u64 new_size, u64 alignment, wapp_intern void *mem_arena_realloc_aligned(void *ptr, u64 old_size, u64 new_size, u64 alignment,
void *alloc_obj) { void *alloc_obj) {
Arena *arena = (Arena *)alloc_obj; Arena *arena = (Arena *)alloc_obj;
return wapp_mem_arena_realloc_aligned(arena, ptr, old_size, new_size, alignment); return wapp_mem_arena_realloc_aligned(arena, ptr, old_size, new_size, alignment);
} }

View File

@@ -12,13 +12,13 @@
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
#define wapp_mem_arena_allocator_init(base_capacity) \ #define wapp_mem_arena_allocator_init(base_capacity) \
(wapp_mem_arena_allocator_init_custom(base_capacity, WAPP_MEM_ALLOC_RESERVE, false)) (wapp_mem_arena_allocator_init_custom(base_capacity, WAPP_MEM_ALLOC_RESERVE, false))
#define wapp_mem_arena_allocator_init_commit(base_capacity) \ #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)) (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) \ #define wapp_mem_arena_allocator_init_zero(base_capacity) \
(wapp_mem_arena_allocator_init_custom(base_capacity, WAPP_MEM_ALLOC_RESERVE, true)) (wapp_mem_arena_allocator_init_custom(base_capacity, WAPP_MEM_ALLOC_RESERVE, true))
#define wapp_mem_arena_allocator_init_commit_and_zero(base_capacity) \ #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)) (wapp_mem_arena_allocator_init_custom(base_capacity, WAPP_MEM_ALLOC_RESERVE | WAPP_MEM_ALLOC_COMMIT, true))
/** /**
@@ -33,8 +33,11 @@ BEGIN_C_LINKAGE
* the Arena is initialised. Wrapper macros are provided for easier use. * the Arena is initialised. Wrapper macros are provided for easier use.
*/ */
Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags flags, b8 zero_buffer); Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags flags, b8 zero_buffer);
void wapp_mem_arena_allocator_clear(Allocator *allocator); Allocator wapp_mem_arena_allocator_init_with_buffer(u8 *buffer, u64 buffer_size);
void wapp_mem_arena_allocator_destroy(Allocator *allocator); void wapp_mem_arena_allocator_temp_begin(const Allocator *allocator);
void wapp_mem_arena_allocator_temp_end(const Allocator *allocator);
void wapp_mem_arena_allocator_clear(Allocator *allocator);
void wapp_mem_arena_allocator_destroy(Allocator *allocator);
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE

View File

@@ -29,32 +29,33 @@ u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts) {
} }
// Handle first node // Handle first node
const Str8Node *first_node = wapp_dbl_list_get(Str8, Str8Node, parts, 0); Str8 *first_node = wapp_dbl_list_get(Str8, parts, 0);
wapp_str8_copy_str8_capped(dst, first_node->item); wapp_str8_copy_str8_capped(dst, first_node);
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
const Str8Node *node = first_node; Str8 *node = first_node;
u64 node_index = 1; u64 node_index = 1;
b8 running = node_index < parts->node_count; b8 running = node_index < parts->node_count;
while (running && node->next) { while (running) {
node = node->next; node = wapp_dbl_list_get(Str8, parts, node_index);
if (node->item->size == 0) { if (node->size == 0) {
continue; goto CPATH_JOIN_LOOP_END;
} }
if (dst->size > 0) { if (dst->size > 0) {
char dst_last = wapp_str8_get(dst, dst->size - 1); char dst_last = wapp_str8_get(dst, dst->size - 1);
char node_start = wapp_str8_get(node->item, 0); char node_start = wapp_str8_get(node, 0);
b8 add_path_sep = dst_last != WAPP_PATH_SEP && node_start != WAPP_PATH_SEP; b8 add_path_sep = dst_last != WAPP_PATH_SEP && node_start != WAPP_PATH_SEP;
if (add_path_sep) { if (add_path_sep) {
wapp_str8_concat_capped(dst, &separator); wapp_str8_concat_capped(dst, &separator);
} }
} }
wapp_str8_concat_capped(dst, node->item); wapp_str8_concat_capped(dst, node);
CPATH_JOIN_LOOP_END:
++node_index; ++node_index;
running = node_index < parts->node_count; running = node_index < parts->node_count;
} }
@@ -68,8 +69,8 @@ Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels) {
goto RETURN_DIRUP; goto RETURN_DIRUP;
} }
b8 absolute = wapp_str8_get(path, 0) == WAPP_PATH_SEP; b8 absolute = wapp_str8_get(path, 0) == WAPP_PATH_SEP;
Str8 separator = wapp_str8_buf(4); Str8 separator = wapp_str8_buf(4);
wapp_str8_push_back(&separator, WAPP_PATH_SEP); wapp_str8_push_back(&separator, WAPP_PATH_SEP);
if (path->size == 0) { if (path->size == 0) {
@@ -106,13 +107,13 @@ Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels) {
wapp_str8_push_back(output, absolute ? WAPP_PATH_SEP : '.'); wapp_str8_push_back(output, absolute ? WAPP_PATH_SEP : '.');
} else { } else {
for (u64 i = 0; i < levels; ++i) { for (u64 i = 0; i < levels; ++i) {
wapp_dbl_list_pop_back(Str8, Str8Node, parts); wapp_dbl_list_pop_back(Str8, parts);
} }
u64 alignment = sizeof(void *) * 2; u64 alignment = sizeof(void *) * 2;
u64 alloc_size = wapp_str8_list_total_size(parts) + parts->node_count * separator.size; u64 alloc_size = wapp_str8_list_total_size(parts) + parts->node_count * separator.size;
u64 modulo = alloc_size & (alignment - 1); u64 modulo = alloc_size & (alignment - 1);
alloc_size += alignment - modulo; alloc_size += alignment - modulo;
output = wapp_str8_alloc_buf(allocator, alloc_size); output = wapp_str8_alloc_buf(allocator, alloc_size);
if (output) { if (output) {

View File

@@ -18,7 +18,7 @@ BEGIN_C_LINKAGE
#define WAPP_PATH_MAX PATH_MAX #define WAPP_PATH_MAX PATH_MAX
#elif defined(WAPP_PLATFORM_WINDOWS) #elif defined(WAPP_PLATFORM_WINDOWS)
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <Windows.h>
#define WAPP_PATH_SEP '\\' #define WAPP_PATH_SEP '\\'
#define WAPP_PATH_MAX MAX_PATH #define WAPP_PATH_MAX MAX_PATH
#else #else
@@ -35,8 +35,8 @@ enum {
CPATH_JOIN_INSUFFICIENT_DST_CAPACITY, CPATH_JOIN_INSUFFICIENT_DST_CAPACITY,
}; };
u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts); u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts);
Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels); Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels);
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE

View File

@@ -6,71 +6,70 @@
#include "../../common/aliases/aliases.h" #include "../../common/aliases/aliases.h"
#include "../../base/array/array.h" #include "../../base/array/array.h"
#include "../../base/strings/str8/str8.h" #include "../../base/strings/str8/str8.h"
#include <stdio.h>
File *wapp_file_open(Str8RO *filepath, FileAccessMode mode) { WFile *wapp_file_open(const Allocator *allocator, Str8RO *filepath, FileAccessMode mode) {
wapp_persist const char *modes[FILE_ACCESS_MODE_COUNT] = { wapp_debug_assert(allocator != NULL && filepath != NULL, "`allocator` and `filepath` should not be NULL");
[WAPP_FA_MODE_R] = "r",
[WAPP_FA_MODE_W] = "w",
[WAPP_FA_MODE_A] = "a",
[WAPP_FA_MODE_R_EX] = "r+",
[WAPP_FA_MODE_W_EX] = "w+",
[WAPP_FA_MODE_A_EX] = "a+",
[WAPP_FA_MODE_RB] = "rb",
[WAPP_FA_MODE_WB] = "wb",
[WAPP_FA_MODE_AB] = "ab",
[WAPP_FA_MODE_RB_EX] = "rb+",
[WAPP_FA_MODE_WB_EX] = "wb+",
[WAPP_FA_MODE_AB_EX] = "ab+",
[WAPP_FA_MODE_WX] = "wx",
[WAPP_FA_MODE_WX_EX] = "wx+",
[WAPP_FA_MODE_WBX] = "wbx",
[WAPP_FA_MODE_WBX_EX] = "wbx+",
};
wapp_persist c8 tmp[WAPP_PATH_MAX] = {0};
wapp_debug_assert(filepath->size < WAPP_PATH_MAX, "`filepath` exceeds max path limit."); wapp_debug_assert(filepath->size < WAPP_PATH_MAX, "`filepath` exceeds max path limit.");
return _file_open(allocator, filepath, mode);
memset(tmp, 0, WAPP_PATH_MAX);
memcpy(tmp, filepath->buf, filepath->size);
return fopen((const char *)tmp, modes[mode]);
} }
u64 wapp_file_get_current_position(File *file) { i64 wapp_file_get_current_position(WFile *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL."); wapp_debug_assert(file != NULL, "`file` should not be NULL.");
return (u64)ftell(file); return _file_seek(file, 0, WAPP_SEEK_CURRENT);
} }
i32 wapp_file_seek(File *file, u64 offset, FileSeekOrigin origin) { i64 wapp_file_seek(WFile *file, i64 offset, FileSeekOrigin origin) {
wapp_debug_assert(file != NULL, "`file` should not be NULL."); wapp_debug_assert(file != NULL, "`file` should not be NULL.");
// TODO (Abdelrahman): Revisit conversion to long return _file_seek(file, offset, origin);
return fseek(file, (long)offset, origin);
} }
u64 wapp_file_get_length(File *file) { i64 wapp_file_get_length(WFile *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL."); wapp_debug_assert(file != NULL, "`file` should not be NULL.");
u64 current = wapp_file_get_current_position(file); i64 current = wapp_file_get_current_position(file);
wapp_file_seek(file, 0, WAPP_SEEK_END); _file_seek(file, 0, WAPP_SEEK_END);
u64 output = ftell(file); i64 output = wapp_file_get_current_position(file);
// Restore position // Restore position
wapp_file_seek(file, current, WAPP_SEEK_START); _file_seek(file, current, WAPP_SEEK_START);
return output; return output;
} }
u64 wapp_file_read(GenericArray *dst_buf, File *file, u64 item_count) { u64 wapp_file_read(void *dst_buf, WFile *file, u64 byte_count) {
wapp_debug_assert(dst_buf != NULL && file != NULL, wapp_debug_assert(dst_buf != NULL && file != NULL,
"`dst_buf` and `file` should not be NULL."); "`dst_buf` and `file` should not be NULL.");
u64 file_length = wapp_file_get_length(file); i64 file_length = wapp_file_get_length(file);
u64 item_size = dst_buf->item_size; if (file_length < 0) {
u64 dst_byte_capacity = dst_buf->capacity * item_size; return 0;
u64 req_byte_count = item_count * item_size; }
u64 copy_byte_count = 0;
return _file_read(dst_buf, byte_count, file, file_length);
}
i64 wapp_file_write(const void *src_buf, WFile *file, u64 byte_count) {
wapp_debug_assert(src_buf != NULL && file != NULL,
"`src_buf` and `file` should not be NULL.");
return _file_write(src_buf, file, byte_count);
}
u64 wapp_file_read_array(GenericArray dst_buf, WFile *file, u64 item_count) {
wapp_debug_assert(dst_buf != NULL && file != NULL,
"`dst_buf` and `file` should not be NULL.");
i64 _file_length = wapp_file_get_length(file);
if (_file_length < 0) {
return 0;
}
u64 file_length = (u64)_file_length;
u64 item_size = wapp_array_item_size(dst_buf);
u64 dst_byte_capacity = wapp_array_capacity(dst_buf) * item_size;
u64 req_byte_count = item_count * item_size;
u64 copy_byte_count = 0;
if (req_byte_count <= file_length && req_byte_count <= dst_byte_capacity) { if (req_byte_count <= file_length && req_byte_count <= dst_byte_capacity) {
copy_byte_count = req_byte_count; copy_byte_count = req_byte_count;
@@ -78,32 +77,53 @@ u64 wapp_file_read(GenericArray *dst_buf, File *file, u64 item_count) {
copy_byte_count = file_length <= dst_byte_capacity ? file_length : dst_byte_capacity; copy_byte_count = file_length <= dst_byte_capacity ? file_length : dst_byte_capacity;
} }
u64 count = fread(dst_buf->items, sizeof(u8), copy_byte_count, file); u64 byte_count = _file_read(dst_buf, copy_byte_count, file, file_length);
if (ferror(file)) { return 0; } if (byte_count == 0) {
return 0;
}
dst_buf->count = count / item_size; wapp_array_set_count(dst_buf, byte_count / item_size);
return dst_buf->count; return wapp_array_count(dst_buf);
} }
u64 wapp_file_write(const GenericArray *src_buf, File *file, u64 item_count) { i64 wapp_file_write_array(const GenericArray src_buf, WFile *file, u64 item_count) {
wapp_debug_assert(src_buf != NULL && file != NULL, wapp_debug_assert(src_buf != NULL && file != NULL,
"`src_buf` and `file` should not be NULL."); "`src_buf` and `file` should not be NULL.");
u64 item_size = src_buf->item_size; u64 item_size = wapp_array_item_size(src_buf);
u64 src_byte_count = src_buf->count * item_size; u64 src_byte_count = wapp_array_count(src_buf) * item_size;
u64 req_byte_count = item_count * item_size; u64 req_byte_count = item_count * item_size;
u64 to_copy = req_byte_count <= src_byte_count ? req_byte_count : src_byte_count; u64 to_copy = req_byte_count <= src_byte_count ? req_byte_count : src_byte_count;
return fwrite(src_buf->items, sizeof(u8), to_copy, file); i64 bytes_written = _file_write(src_buf, file, to_copy);
if (bytes_written < 0) {
return 0;
}
return (u64)bytes_written / item_size;
} }
i32 wapp_file_flush(File *file) { i32 wapp_file_flush(WFile *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL."); wapp_debug_assert(file != NULL, "`file` should not be NULL.");
return fflush(file); return _file_flush(file);
} }
i32 wapp_file_close(File *file) { i32 wapp_file_close(WFile *file) {
wapp_debug_assert(file != NULL, "`file` should not be NULL."); wapp_debug_assert(file != NULL, "`file` should not be NULL.");
return fclose(file); return _file_close(file);
}
i32 wapp_file_rename(Str8RO *old_filepath, Str8RO *new_filepath) {
wapp_debug_assert(old_filepath != NULL && new_filepath != NULL,
"`old_filepath` and `new_filepath` should not be NULL");
wapp_debug_assert(old_filepath->size < WAPP_PATH_MAX, "`old_filepath` exceeds max path limit.");
wapp_debug_assert(new_filepath->size < WAPP_PATH_MAX, "`new_filepath` exceeds max path limit.");
return _file_rename(old_filepath, new_filepath);
}
i32 wapp_file_remove(Str8RO *filepath) {
wapp_debug_assert(filepath != NULL, "`filepath` should not be NULL");
wapp_debug_assert(filepath->size < WAPP_PATH_MAX, "`filepath` exceeds max path limit.");
return _file_remove(filepath);
} }

View File

@@ -3,51 +3,58 @@
#ifndef FILE_H #ifndef FILE_H
#define FILE_H #define FILE_H
#include "../../base/mem/allocator/mem_allocator.h"
#include "../../common/aliases/aliases.h" #include "../../common/aliases/aliases.h"
#include "../../base/strings/str8/str8.h" #include "../../base/strings/str8/str8.h"
#include <stdio.h>
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
typedef FILE File; typedef struct WFile WFile;
typedef enum { typedef enum {
WAPP_FA_MODE_R, // Equivalent to r WAPP_ACCESS_READ, // Equivalent to r
WAPP_FA_MODE_W, // Equivalent to w WAPP_ACCESS_WRITE, // Equivalent to w
WAPP_FA_MODE_A, // Equivalent to a WAPP_ACCESS_APPEND, // Equivalent to a
WAPP_FA_MODE_R_EX, // Equivalent to r+ WAPP_ACCESS_READ_EX, // Equivalent to r+
WAPP_FA_MODE_W_EX, // Equivalent to w+ WAPP_ACCESS_WRITE_EX, // Equivalent to w+
WAPP_FA_MODE_A_EX, // Equivalent to a+ WAPP_ACCESS_APPEND_EX, // Equivalent to a+
WAPP_FA_MODE_RB, // Equivalent to rb WAPP_ACCESS_WRITE_FAIL_ON_EXIST, // Equivalent to wx
WAPP_FA_MODE_WB, // Equivalent to wb WAPP_ACCESS_WRITE_FAIL_ON_EXIST_EX, // Equivalent to wx+
WAPP_FA_MODE_AB, // Equivalent to ab
WAPP_FA_MODE_RB_EX, // Equivalent to rb+
WAPP_FA_MODE_WB_EX, // Equivalent to wb+
WAPP_FA_MODE_AB_EX, // Equivalent to ab+
WAPP_FA_MODE_WX, // Equivalent to wx
WAPP_FA_MODE_WX_EX, // Equivalent to wx+
WAPP_FA_MODE_WBX, // Equivalent to wbx
WAPP_FA_MODE_WBX_EX, // Equivalent to wbx+
FILE_ACCESS_MODE_COUNT, FILE_ACCESS_MODE_COUNT,
} FileAccessMode; } FileAccessMode;
typedef enum { typedef enum {
WAPP_SEEK_START = SEEK_SET, WAPP_SEEK_START,
WAPP_SEEK_CURRENT = SEEK_CUR, WAPP_SEEK_CURRENT,
WAPP_SEEK_END = SEEK_END, WAPP_SEEK_END,
FILE_SEEK_ORIGIN_COUNT,
} FileSeekOrigin; } FileSeekOrigin;
File *wapp_file_open(Str8RO *filename, FileAccessMode mode); WFile *wapp_file_open(const Allocator *allocator, Str8RO *filepath, FileAccessMode mode);
u64 wapp_file_get_current_position(File *file); i64 wapp_file_get_current_position(WFile *file);
i32 wapp_file_seek(File *file, u64 offset, FileSeekOrigin origin); i64 wapp_file_seek(WFile *file, i64 offset, FileSeekOrigin origin);
u64 wapp_file_get_length(File *file); i64 wapp_file_get_length(WFile *file);
u64 wapp_file_read(GenericArray *dst_buf, File *file, u64 item_count); u64 wapp_file_read(void *dst_buf, WFile *file, u64 byte_count);
u64 wapp_file_write(const GenericArray *src_buf, File *file, u64 item_count); i64 wapp_file_write(const void *src_buf, WFile *file, u64 byte_count);
i32 wapp_file_flush(File *file); u64 wapp_file_read_array(GenericArray dst_buf, WFile *file, u64 item_count);
i32 wapp_file_close(File *file); i64 wapp_file_write_array(const GenericArray src_buf, WFile *file, u64 item_count);
i32 wapp_file_flush(WFile *file);
i32 wapp_file_close(WFile *file);
i32 wapp_file_rename(Str8RO *old_filepath, Str8RO *new_filepath);
i32 wapp_file_remove(Str8RO *filepath);
extern WFile *_file_open(const Allocator *allocator, Str8RO *filepath, FileAccessMode mode);
extern i64 _file_seek(WFile *file, i64 offset, FileSeekOrigin origin);
extern u64 _file_read(void *dst_buf, u64 byte_count, WFile *file, u64 file_length);
extern i64 _file_write(const void *src_buf, WFile *file, u64 byte_count);
extern i32 _file_flush(WFile *file);
extern i32 _file_close(WFile *file);
extern i32 _file_rename(Str8RO *old_filepath, Str8RO *new_filepath);
extern i32 _file_remove(Str8RO *filepath);
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE END_C_LINKAGE

View File

@@ -0,0 +1,118 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "file_posix.h"
#include "../../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_POSIX
#include "../file.h"
#include "../../cpath/cpath.h"
#include "../../../common/aliases/aliases.h"
#include "../../../base/array/array.h"
#include "../../../base/strings/str8/str8.h"
#ifdef WAPP_PLATFORM_APPLE
#define _FILE_OFFSET_BITS 64
#define lseek64 lseek
#endif // !WAPP_PLATFORM_APPLE
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
wapp_intern i32 file_flags[FILE_ACCESS_MODE_COUNT] = {
[WAPP_ACCESS_READ] = O_RDONLY,
[WAPP_ACCESS_WRITE] = O_WRONLY | O_CREAT,
[WAPP_ACCESS_APPEND] = O_WRONLY | O_APPEND | O_CREAT,
[WAPP_ACCESS_READ_EX] = O_RDWR,
[WAPP_ACCESS_WRITE_EX] = O_RDWR | O_CREAT,
[WAPP_ACCESS_APPEND_EX] = O_RDWR | O_APPEND | O_CREAT,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST] = O_WRONLY | O_CREAT | O_EXCL,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST_EX] = O_RDWR | O_CREAT | O_EXCL,
};
wapp_intern mode_t file_modes[FILE_ACCESS_MODE_COUNT] = {
[WAPP_ACCESS_READ] = 0,
[WAPP_ACCESS_WRITE] = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
[WAPP_ACCESS_APPEND] = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
[WAPP_ACCESS_READ_EX] = 0,
[WAPP_ACCESS_WRITE_EX] = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
[WAPP_ACCESS_APPEND_EX] = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST] = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST_EX] = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
};
wapp_intern i32 file_seek_origins[FILE_SEEK_ORIGIN_COUNT] = {
[WAPP_SEEK_START] = SEEK_SET,
[WAPP_SEEK_CURRENT] = SEEK_CUR,
[WAPP_SEEK_END] = SEEK_END,
};
WFile *_file_open(const Allocator *allocator, Str8RO *filepath, FileAccessMode mode) {
wapp_persist c8 tmp[WAPP_PATH_MAX] = {0};
memset(tmp, 0, WAPP_PATH_MAX);
memcpy(tmp, filepath->buf, filepath->size);
i32 fd = open((const char *)tmp, file_flags[mode], file_modes[mode]);
if (fd < 0) {
return NULL;
}
WFile *output = wapp_mem_allocator_alloc(allocator, sizeof(WFile));
if (output) {
output->fd = fd;
}
return output;
}
i64 _file_seek(WFile *file, i64 offset, FileSeekOrigin origin) {
return lseek64(file->fd, offset, file_seek_origins[origin]);
}
u64 _file_read(void *dst_buf, u64 byte_count, WFile *file, u64 file_length) {
u64 copy_byte_count = file_length <= byte_count ? file_length : byte_count;
i64 count = read(file->fd, dst_buf, copy_byte_count);
if (count < 0) { return 0; }
return count;
}
i64 _file_write(const void *src_buf, WFile *file, u64 byte_count) {
return write(file->fd, src_buf, byte_count);
}
i32 _file_flush(WFile *file) {
return fsync(file->fd);
}
i32 _file_close(WFile *file) {
return close(file->fd);
}
i32 _file_rename(Str8RO *old_filepath, Str8RO *new_filepath) {
wapp_persist c8 old_tmp[WAPP_PATH_MAX] = {0};
wapp_persist c8 new_tmp[WAPP_PATH_MAX] = {0};
memset(old_tmp, 0, WAPP_PATH_MAX);
memcpy(old_tmp, old_filepath->buf, old_filepath->size);
memset(new_tmp, 0, WAPP_PATH_MAX);
memcpy(new_tmp, new_filepath->buf, new_filepath->size);
i32 link_result = link((const char *)old_tmp, (const char *)new_tmp);
if (link_result == 0) {
_file_remove(old_filepath);
}
return link_result;
}
i32 _file_remove(Str8RO *filepath) {
wapp_persist c8 tmp[WAPP_PATH_MAX] = {0};
memset(tmp, 0, WAPP_PATH_MAX);
memcpy(tmp, filepath->buf, filepath->size);
return unlink((const char *)tmp);
}
#endif // !WAPP_PLATFORM_POSIX

View File

@@ -0,0 +1,27 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef FILE_POSIX_H
#define FILE_POSIX_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_POSIX
#define END_OF_LINE "\n"
struct WFile {
i32 fd;
};
#endif // !WAPP_PLATFORM_POSIX
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !FILE_POSIX_H

159
src/os/file/win/file_win.c Normal file
View File

@@ -0,0 +1,159 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "file_win.h"
#include "../../../common/platform/platform.h"
#ifdef WAPP_PLATFORM_WINDOWS
#include "../file.h"
#include "../../cpath/cpath.h"
#include "../../../common/aliases/aliases.h"
#include "../../../base/array/array.h"
#include "../../../base/strings/str8/str8.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <fileapi.h>
#include <intsafe.h>
wapp_intern DWORD file_accesses[FILE_ACCESS_MODE_COUNT] = {
[WAPP_ACCESS_READ] = FILE_READ_DATA,
[WAPP_ACCESS_WRITE] = FILE_WRITE_DATA,
[WAPP_ACCESS_APPEND] = FILE_APPEND_DATA,
[WAPP_ACCESS_READ_EX] = FILE_READ_DATA | FILE_WRITE_DATA,
[WAPP_ACCESS_WRITE_EX] = FILE_READ_DATA | FILE_WRITE_DATA,
[WAPP_ACCESS_APPEND_EX] = FILE_READ_DATA | FILE_APPEND_DATA,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST] = FILE_WRITE_DATA,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST_EX] = FILE_READ_DATA | FILE_WRITE_DATA,
};
wapp_intern DWORD creation_dispositions[FILE_ACCESS_MODE_COUNT] = {
[WAPP_ACCESS_READ] = OPEN_EXISTING,
[WAPP_ACCESS_WRITE] = CREATE_ALWAYS,
[WAPP_ACCESS_APPEND] = OPEN_ALWAYS,
[WAPP_ACCESS_READ_EX] = OPEN_EXISTING,
[WAPP_ACCESS_WRITE_EX] = CREATE_ALWAYS,
[WAPP_ACCESS_APPEND_EX] = OPEN_ALWAYS,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST] = CREATE_NEW,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST_EX] = CREATE_NEW,
};
wapp_intern DWORD sharing_modes[FILE_ACCESS_MODE_COUNT] = {
[WAPP_ACCESS_READ] = FILE_SHARE_READ | FILE_SHARE_WRITE,
[WAPP_ACCESS_WRITE] = FILE_SHARE_READ,
[WAPP_ACCESS_APPEND] = FILE_SHARE_READ,
[WAPP_ACCESS_READ_EX] = FILE_SHARE_READ | FILE_SHARE_WRITE,
[WAPP_ACCESS_WRITE_EX] = FILE_SHARE_READ,
[WAPP_ACCESS_APPEND_EX] = FILE_SHARE_READ,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST] = FILE_SHARE_READ,
[WAPP_ACCESS_WRITE_FAIL_ON_EXIST_EX] = FILE_SHARE_READ,
};
wapp_intern DWORD file_seek_origins[FILE_SEEK_ORIGIN_COUNT] = {
[WAPP_SEEK_START] = FILE_BEGIN,
[WAPP_SEEK_CURRENT] = FILE_CURRENT,
[WAPP_SEEK_END] = FILE_END,
};
WFile *_file_open(const Allocator *allocator, Str8RO *filepath, FileAccessMode mode) {
wapp_persist c8 tmp[WAPP_PATH_MAX] = {0};
memset(tmp, 0, WAPP_PATH_MAX);
memcpy(tmp, filepath->buf, filepath->size);
HANDLE fh = CreateFileA((LPCSTR)tmp,
file_accesses[mode],
sharing_modes[mode],
NULL,
creation_dispositions[mode],
FILE_ATTRIBUTE_NORMAL,
NULL);
if (fh == INVALID_HANDLE_VALUE) {
return NULL;
}
WFile *output = wapp_mem_allocator_alloc(allocator, sizeof(WFile));
if (output) {
output->fh = fh;
}
return output;
}
i64 _file_seek(WFile *file, i64 offset, FileSeekOrigin origin) {
LARGE_INTEGER distance = {0};
LARGE_INTEGER output = {0};
distance.QuadPart = offset;
if (!SetFilePointerEx(file->fh, distance, &output, file_seek_origins[origin])) {
return -1;
}
return output.QuadPart;
}
u64 _file_read(void* dst_buf, u64 byte_count, WFile* file, u64 file_length) {
u64 copy_byte_count = file_length <= byte_count ? file_length : byte_count;
wapp_debug_assert(copy_byte_count <= DWORD_MAX, "Attempting to read large number of bytes at once");
DWORD read_count = 0;
if (!ReadFile(file->fh, dst_buf, (DWORD)copy_byte_count, &read_count, NULL)) {
return 0;
}
return (u64)read_count;
}
i64 _file_write(const void *src_buf, WFile *file, u64 byte_count) {
wapp_debug_assert(byte_count <= DWORD_MAX, "Attempting to write large number of bytes at once");
DWORD write_count = 0;
if (!WriteFile(file->fh, src_buf, (DWORD)byte_count, &write_count, NULL)) {
return 0;
}
return (i64)write_count;
}
i32 _file_flush(WFile *file) {
if (!FlushFileBuffers(file->fh)) {
return -1;
}
return 0;
}
i32 _file_close(WFile *file) {
if (!CloseHandle(file->fh)) {
return -1;
}
return 0;
}
i32 _file_rename(Str8RO *old_filepath, Str8RO *new_filepath) {
wapp_persist c8 old_tmp[WAPP_PATH_MAX] = {0};
wapp_persist c8 new_tmp[WAPP_PATH_MAX] = {0};
memset(old_tmp, 0, WAPP_PATH_MAX);
memcpy(old_tmp, old_filepath->buf, old_filepath->size);
memset(new_tmp, 0, WAPP_PATH_MAX);
memcpy(new_tmp, new_filepath->buf, new_filepath->size);
if (!MoveFile((LPCSTR)old_tmp, (LPCSTR)new_tmp)) {
return -1;
}
return 0;
}
i32 _file_remove(Str8RO *filepath) {
wapp_persist c8 tmp[WAPP_PATH_MAX] = {0};
memset(tmp, 0, WAPP_PATH_MAX);
memcpy(tmp, filepath->buf, filepath->size);
if (!DeleteFile((LPCSTR)tmp)) {
return -1;
}
return 0;
}
#endif // !WAPP_PLATFORM_WINDOWS

View File

@@ -0,0 +1,31 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef FILE_WIN_H
#define FILE_WIN_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_WINDOWS
#define END_OF_LINE "\r\n"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <fileapi.h>
struct WFile {
HANDLE fh;
};
#endif // !WAPP_PLATFORM_WINDOWS
#ifdef WAPP_PLATFORM_CPP
END_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP
#endif // !FILE_WIN_H

View File

@@ -10,12 +10,12 @@
#include <sys/mman.h> #include <sys/mman.h>
wapp_intern const i32 access_types[] = { wapp_intern const i32 access_types[] = {
[WAPP_MEM_ACCESS_NONE] = PROT_NONE, [WAPP_MEM_ACCESS_NONE] = PROT_NONE,
[WAPP_MEM_ACCESS_READ_ONLY] = PROT_READ, [WAPP_MEM_ACCESS_READ_ONLY] = PROT_READ,
[WAPP_MEM_ACCESS_EXEC_ONLY] = PROT_EXEC, [WAPP_MEM_ACCESS_EXEC_ONLY] = PROT_EXEC,
[WAPP_MEM_ACCESS_READ_WRITE] = PROT_READ | PROT_WRITE, [WAPP_MEM_ACCESS_READ_WRITE] = PROT_READ | PROT_WRITE,
[WAPP_MEM_ACCESS_READ_EXEC] = PROT_READ | PROT_EXEC, [WAPP_MEM_ACCESS_READ_EXEC] = PROT_READ | PROT_EXEC,
[WAPP_MEM_ACCESS_READ_WRITE_EXEC] = PROT_READ | PROT_WRITE | PROT_EXEC, [WAPP_MEM_ACCESS_READ_WRITE_EXEC] = PROT_READ | PROT_WRITE | PROT_EXEC,
}; };
void *os_mem_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) { void *os_mem_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) {

View File

@@ -15,14 +15,14 @@ BEGIN_C_LINKAGE
typedef enum mem_alloc_flags { typedef enum mem_alloc_flags {
#if defined(WAPP_PLATFORM_LINUX) || defined(WAPP_PLATFORM_GNU) #if defined(WAPP_PLATFORM_LINUX) || defined(WAPP_PLATFORM_GNU)
WAPP_MEM_ALLOC_RESERVE = 0, WAPP_MEM_ALLOC_RESERVE = 0,
WAPP_MEM_ALLOC_COMMIT = MAP_POPULATE, WAPP_MEM_ALLOC_COMMIT = MAP_POPULATE,
#elif defined(WAPP_PLATFORM_FREE_BSD) #elif defined(WAPP_PLATFORM_FREE_BSD)
WAPP_MEM_ALLOC_RESERVE = 0, WAPP_MEM_ALLOC_RESERVE = 0,
WAPP_MEM_ALLOC_COMMIT = MAP_PREFAULT_READ, WAPP_MEM_ALLOC_COMMIT = MAP_PREFAULT_READ,
#elif defined(WAPP_PLATFORM_BSD) || defined(WAPP_PLATFORM_UNIX) || defined(WAPP_PLATFORM_APPLE) #elif defined(WAPP_PLATFORM_BSD) || defined(WAPP_PLATFORM_UNIX) || defined(WAPP_PLATFORM_APPLE)
WAPP_MEM_ALLOC_RESERVE = 0, WAPP_MEM_ALLOC_RESERVE = 0,
WAPP_MEM_ALLOC_COMMIT = 0, WAPP_MEM_ALLOC_COMMIT = 0,
#endif #endif
} MemAllocFlags; } MemAllocFlags;

View File

@@ -13,12 +13,12 @@
#include <memoryapi.h> #include <memoryapi.h>
wapp_intern const i32 access_types[] = { wapp_intern const i32 access_types[] = {
[WAPP_MEM_ACCESS_NONE] = PAGE_NOACCESS, [WAPP_MEM_ACCESS_NONE] = PAGE_NOACCESS,
[WAPP_MEM_ACCESS_READ_ONLY] = PAGE_READONLY, [WAPP_MEM_ACCESS_READ_ONLY] = PAGE_READONLY,
[WAPP_MEM_ACCESS_EXEC_ONLY] = PAGE_EXECUTE, [WAPP_MEM_ACCESS_EXEC_ONLY] = PAGE_EXECUTE,
[WAPP_MEM_ACCESS_READ_WRITE] = PAGE_READWRITE, [WAPP_MEM_ACCESS_READ_WRITE] = PAGE_READWRITE,
[WAPP_MEM_ACCESS_READ_EXEC] = PAGE_EXECUTE_READ, [WAPP_MEM_ACCESS_READ_EXEC] = PAGE_EXECUTE_READ,
[WAPP_MEM_ACCESS_READ_WRITE_EXEC] = PAGE_EXECUTE_READWRITE, [WAPP_MEM_ACCESS_READ_WRITE_EXEC] = PAGE_EXECUTE_READWRITE,
}; };
void *os_mem_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) { void *os_mem_allocate(void *addr, u64 size, MemAccess access, MemAllocFlags flags, MemInitType type) {

View File

@@ -16,8 +16,8 @@ BEGIN_C_LINKAGE
#include <memoryapi.h> #include <memoryapi.h>
typedef enum mem_alloc_flags { typedef enum mem_alloc_flags {
WAPP_MEM_ALLOC_RESERVE = MEM_RESERVE, WAPP_MEM_ALLOC_RESERVE = MEM_RESERVE,
WAPP_MEM_ALLOC_COMMIT = MEM_COMMIT, WAPP_MEM_ALLOC_COMMIT = MEM_COMMIT,
} MemAllocFlags; } MemAllocFlags;
#endif // !WAPP_PLATFORM_WINDOWS #endif // !WAPP_PLATFORM_WINDOWS

View File

@@ -71,9 +71,9 @@ wapp_intern CMDResult execute_command(Str8RO *cmd, CMDOutHandling out_handling,
fp = NULL; fp = NULL;
output = (CMDResult){ output = (CMDResult){
.exited = true, .exited = true,
.exit_code = st, .exit_code = st,
.error = SHELL_ERR_NO_ERROR, .error = SHELL_ERR_NO_ERROR,
}; };
EXECUTE_COMMAND_CLOSE: EXECUTE_COMMAND_CLOSE:

View File

@@ -5,6 +5,7 @@
#include "../../../common/aliases/aliases.h" #include "../../../common/aliases/aliases.h"
#include "../../../common/platform/platform.h" #include "../../../common/platform/platform.h"
#include "../../../common/misc/misc_utils.h"
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
@@ -25,16 +26,13 @@ typedef enum {
SHELL_ERR_PROC_EXIT_FAIL, SHELL_ERR_PROC_EXIT_FAIL,
} CMDError; } CMDError;
typedef struct commander_result CMDResult; typedef struct CMDResult CMDResult;
struct commander_result { struct CMDResult {
i32 exit_code; i32 exit_code;
CMDError error; CMDError error;
b8 exited; b8 exited;
#ifdef WAPP_PLATFORM_WINDOWS wapp_misc_utils_reserve_padding(sizeof(b8) + sizeof(i32) + sizeof(CMDError));
#include "../../../../common/misc/misc_utils.h"
wapp_misc_utils_padding_size(sizeof(b8) + sizeof(i32) + sizeof(CMDError));
#endif // !WAPP_PLATFORM_WINDOWS
}; };
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP

View File

@@ -10,23 +10,23 @@
#include <stdio.h> #include <stdio.h>
wapp_intern Str8RO colours[COUNT_TERM_COLOUR] = { wapp_intern Str8RO colours[COUNT_TERM_COLOUR] = {
[WAPP_TERM_COLOUR_FG_BLACK] = wapp_str8_lit_ro_initialiser_list("\033[30m"), [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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_FG_BR_WHITE] = wapp_str8_lit_ro_initialiser_list("\033[97m"),
[WAPP_TERM_COLOUR_CLEAR] = wapp_str8_lit_ro_initialiser_list("\033[0m"), [WAPP_TERM_COLOUR_CLEAR] = wapp_str8_lit_ro_initialiser_list("\033[0m"),
}; };
void print_coloured_text(Str8RO *text, TerminalColour colour) { void print_coloured_text(Str8RO *text, TerminalColour colour) {

View File

@@ -7,40 +7,40 @@
#ifdef WAPP_PLATFORM_WINDOWS #ifdef WAPP_PLATFORM_WINDOWS
#include "../terminal_colours.h" #include "../terminal_colours.h"
#include "../../../../../common/misc/misc_utils.h" #include "../../../../common/misc/misc_utils.h"
#include <stdio.h> #include <stdio.h>
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>
typedef struct termcolour_data TermcolourData; typedef struct TermcolourData TermcolourData;
struct termcolour_data { struct TermcolourData {
HANDLE handle; HANDLE handle;
WORD default_colour; WORD default_colour;
WORD current_colour; WORD current_colour;
wapp_misc_utils_padding_size(sizeof(HANDLE) + sizeof(WORD) + sizeof(WORD)); wapp_misc_utils_reserve_padding(sizeof(HANDLE) + sizeof(WORD) + sizeof(WORD));
}; };
wapp_intern void init_data(TermcolourData *data); wapp_intern void init_data(TermcolourData *data);
wapp_intern WORD colours[COUNT_TERM_COLOUR] = { wapp_intern WORD colours[COUNT_TERM_COLOUR] = {
[WAPP_TERM_COLOUR_FG_BLACK] = 0, [WAPP_TERM_COLOUR_FG_BLACK] = 0,
[WAPP_TERM_COLOUR_FG_RED] = FOREGROUND_RED, [WAPP_TERM_COLOUR_FG_RED] = FOREGROUND_RED,
[WAPP_TERM_COLOUR_FG_GREEN] = FOREGROUND_GREEN, [WAPP_TERM_COLOUR_FG_GREEN] = FOREGROUND_GREEN,
[WAPP_TERM_COLOUR_FG_BLUE] = FOREGROUND_BLUE, [WAPP_TERM_COLOUR_FG_BLUE] = FOREGROUND_BLUE,
[WAPP_TERM_COLOUR_FG_CYAN] = FOREGROUND_GREEN | FOREGROUND_BLUE, [WAPP_TERM_COLOUR_FG_CYAN] = FOREGROUND_GREEN | FOREGROUND_BLUE,
[WAPP_TERM_COLOUR_FG_MAGENTA] = FOREGROUND_RED | FOREGROUND_BLUE, [WAPP_TERM_COLOUR_FG_MAGENTA] = FOREGROUND_RED | FOREGROUND_BLUE,
[WAPP_TERM_COLOUR_FG_YELLOW] = FOREGROUND_RED | FOREGROUND_GREEN, [WAPP_TERM_COLOUR_FG_YELLOW] = FOREGROUND_RED | FOREGROUND_GREEN,
[WAPP_TERM_COLOUR_FG_WHITE] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, [WAPP_TERM_COLOUR_FG_WHITE] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
[WAPP_TERM_COLOUR_FG_BR_BLACK] = FOREGROUND_INTENSITY, [WAPP_TERM_COLOUR_FG_BR_BLACK] = FOREGROUND_INTENSITY,
[WAPP_TERM_COLOUR_FG_BR_RED] = FOREGROUND_RED | 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_GREEN] = FOREGROUND_GREEN | FOREGROUND_INTENSITY,
[WAPP_TERM_COLOUR_FG_BR_BLUE] = FOREGROUND_BLUE | 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_CYAN] = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
[WAPP_TERM_COLOUR_FG_BR_MAGENTA] = FOREGROUND_RED | 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_YELLOW] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
[WAPP_TERM_COLOUR_FG_BR_WHITE] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY, [WAPP_TERM_COLOUR_FG_BR_WHITE] = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
}; };
void print_coloured_text(Str8RO *text, TerminalColour colour) { void print_coloured_text(Str8RO *text, TerminalColour colour) {

View File

@@ -12,11 +12,11 @@ BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
#ifdef WAPP_PLATFORM_WINDOWS #ifdef WAPP_PLATFORM_WINDOWS
#define wapp_shell_utils_popen _popen #define wapp_shell_utils_popen _popen
#define wapp_shell_utils_pclose _pclose #define wapp_shell_utils_pclose _pclose
#else #else
#define wapp_shell_utils_popen popen #define wapp_shell_utils_popen popen
#define wapp_shell_utils_pclose pclose #define wapp_shell_utils_pclose pclose
#endif /* ifdef WAPP_PLATFORM_WINDOWS */ #endif /* ifdef WAPP_PLATFORM_WINDOWS */
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP

View File

@@ -5,6 +5,8 @@
#include "wapp_os.h" #include "wapp_os.h"
#include "file/file.c" #include "file/file.c"
#include "file/posix/file_posix.c"
#include "file/win/file_win.c"
#include "shell/termcolour/posix/termcolour_posix.c" #include "shell/termcolour/posix/termcolour_posix.c"
#include "shell/termcolour/win/termcolour_win.c" #include "shell/termcolour/win/termcolour_win.c"
#include "shell/termcolour/termcolour.c" #include "shell/termcolour/termcolour.c"

View File

@@ -4,6 +4,8 @@
#define WAPP_CORE_H #define WAPP_CORE_H
#include "file/file.h" #include "file/file.h"
#include "file/posix/file_posix.h"
#include "file/win/file_win.h"
#include "shell/termcolour/termcolour.h" #include "shell/termcolour/termcolour.h"
#include "shell/termcolour/terminal_colours.h" #include "shell/termcolour/terminal_colours.h"
#include "shell/commander/commander.h" #include "shell/commander/commander.h"

View File

@@ -7,8 +7,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
typedef struct split_mix_64_state SplitMix64State; typedef struct SplitMix64State SplitMix64State;
struct split_mix_64_state { struct SplitMix64State {
u64 seed; u64 seed;
}; };
@@ -70,7 +70,7 @@ u64 wapp_prng_xorshift_256p(XOR256State *state) {
state->w ^= state->x; state->w ^= state->x;
state->y ^= t; state->y ^= t;
state->x = rol64(state->x, 45); state->x = rol64(state->x, 45);
return result; return result;
} }

View File

@@ -10,8 +10,8 @@
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
typedef struct xor_256_state XOR256State; typedef struct XOR256State XOR256State;
struct xor_256_state { struct XOR256State {
u64 x; u64 x;
u64 y; u64 y;
u64 z; u64 z;

View File

@@ -10,21 +10,19 @@
#ifdef WAPP_PLATFORM_CPP #ifdef WAPP_PLATFORM_CPP
BEGIN_C_LINKAGE BEGIN_C_LINKAGE
#define wapp_tester_result(PASSED) (TestFuncResult{wapp_str8_lit_ro(__func__), PASSED}) #define wapp_tester_result(PASSED) (TestFuncResult{wapp_str8_lit_ro(__func__), PASSED, {}})
#else #else
#define wapp_tester_result(PASSED) ((TestFuncResult){.name = wapp_str8_lit_ro(__func__), .passed = PASSED}) #define wapp_tester_result(PASSED) ((TestFuncResult){.name = wapp_str8_lit_ro(__func__), .passed = PASSED})
#endif // !WAPP_PLATFORM_CPP #endif // !WAPP_PLATFORM_CPP
#define wapp_tester_run_tests(...) run_tests(__VA_ARGS__, NULL) #define wapp_tester_run_tests(...) run_tests(__VA_ARGS__, NULL)
typedef struct test_func_result TestFuncResult; typedef struct TestFuncResult TestFuncResult;
struct test_func_result { struct TestFuncResult {
Str8 name; Str8 name;
b8 passed; b8 passed;
#ifdef WAPP_PLATFORM_WINDOWS wapp_misc_utils_reserve_padding(sizeof(Str8) + sizeof(b8));
wapp_misc_utils_padding_size(sizeof(Str8RO) + sizeof(b8));
#endif // WAPP_PLATFORM_WINDOWS
}; };
typedef TestFuncResult(TestFunc)(void); typedef TestFuncResult(TestFunc)(void);

View File

@@ -9,14 +9,14 @@
#define UUID_STR_FORMAT ("%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.12" PRIx64) #define UUID_STR_FORMAT ("%.8" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.4" PRIx64 "-%.12" PRIx64)
typedef struct uuid4 UUID4; typedef struct UUID4 UUID4;
struct uuid4 { struct UUID4 {
u64 high; u64 high;
u64 low; u64 low;
}; };
wapp_intern UUID4 generate_uuid4(void); wapp_intern UUID4 generate_uuid4(void);
wapp_intern void uuid4_to_uuid(const UUID4* uuid4, WUUID *uuid); wapp_intern void uuid4_to_uuid(const UUID4* uuid4, WUUID *uuid);
WUUID *wapp_uuid_init_uuid4(WUUID *uuid) { WUUID *wapp_uuid_init_uuid4(WUUID *uuid) {
wapp_debug_assert(uuid != NULL, "`uuid` should not be NULL"); wapp_debug_assert(uuid != NULL, "`uuid` should not be NULL");
@@ -32,17 +32,17 @@ wapp_intern UUID4 generate_uuid4(void) {
wapp_persist b8 initialised = false; wapp_persist b8 initialised = false;
if (!initialised) { if (!initialised) {
initialised = true; initialised = true;
state = wapp_prng_xorshift_init_state(); state = wapp_prng_xorshift_init_state();
} }
UUID4 uuid = (UUID4){ UUID4 uuid = (UUID4){
.high = wapp_prng_xorshift_256(&state), .high = wapp_prng_xorshift_256(&state),
.low = wapp_prng_xorshift_256(&state), .low = wapp_prng_xorshift_256(&state),
}; };
uuid.high = (uuid.high & 0xffffffffffff0fff) | 0x0000000000004000; uuid.high = (uuid.high & 0xffffffffffff0fff) | 0x0000000000004000;
uuid.low = (uuid.low & 0x3fffffffffffffff) | 0x8000000000000000; uuid.low = (uuid.low & 0x3fffffffffffffff) | 0x8000000000000000;
return uuid; return uuid;
} }

View File

@@ -15,8 +15,8 @@ BEGIN_C_LINKAGE
#define WAPP_UUID_SPEC WAPP_STR8_SPEC #define WAPP_UUID_SPEC WAPP_STR8_SPEC
#define wapp_uuid_varg(WUUID) wapp_str8_varg((WUUID).uuid) #define wapp_uuid_varg(WUUID) wapp_str8_varg((WUUID).uuid)
typedef struct wapp_uuid WUUID; typedef struct WUUID WUUID;
struct wapp_uuid { struct WUUID {
Str8 uuid; Str8 uuid;
}; };

View File

@@ -2,16 +2,66 @@
#include "wapp.h" #include "wapp.h"
#include <stdlib.h> #include <stdlib.h>
// NOTE (Abdelrahman): Cannot query size of Arena here so it's hardcoded. Similarly, since arena
// allocation are aligned to power of 2 boundaries, the number of i32 values needed is hardcoded.
#define TEMP_BUF_SIZE (40 + sizeof(i32) * 8)
wapp_intern u8 temp_buf[TEMP_BUF_SIZE] = {0};
wapp_intern Allocator temp_allocator = {0};
TestFuncResult test_arena_allocator(void) { TestFuncResult test_arena_allocator(void) {
Allocator allocator = wapp_mem_arena_allocator_init(4096); Allocator allocator = wapp_mem_arena_allocator_init(4096);
b8 result = allocator.obj != NULL && allocator.alloc != NULL && b8 result = allocator.obj != NULL && allocator.alloc != NULL &&
allocator.alloc_aligned != NULL && allocator.alloc_aligned != NULL &&
allocator.realloc != NULL && allocator.realloc_aligned != NULL && allocator.realloc != NULL && allocator.realloc_aligned != NULL &&
allocator.free == NULL; allocator.free == NULL;
void *ptr = wapp_mem_allocator_alloc(&allocator, 20); void *ptr = wapp_mem_allocator_alloc(&allocator, 20);
result = result && (ptr != NULL); result = result && (ptr != NULL);
wapp_mem_arena_allocator_destroy(&allocator); wapp_mem_arena_allocator_destroy(&allocator);
return wapp_tester_result(result); return wapp_tester_result(result);
} }
TestFuncResult test_arena_allocator_with_buffer(void) {
u8 buffer[KiB(4)] = {0};
Allocator allocator = wapp_mem_arena_allocator_init_with_buffer(buffer, KiB(4));
b8 result = allocator.obj != NULL && allocator.alloc != NULL &&
allocator.alloc_aligned != NULL &&
allocator.realloc != NULL && allocator.realloc_aligned != NULL &&
allocator.free == NULL;
void *ptr = wapp_mem_allocator_alloc(&allocator, 20);
result = result && (ptr != NULL);
wapp_mem_arena_allocator_destroy(&allocator);
return wapp_tester_result(result);
}
TestFuncResult test_arena_allocator_temp_begin(void) {
temp_allocator = wapp_mem_arena_allocator_init_with_buffer(temp_buf, TEMP_BUF_SIZE);
i32 *num1 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
b8 result = num1 != NULL;
wapp_mem_arena_allocator_temp_begin(&temp_allocator);
i32 *num2 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
result = result && num2 != NULL;
i32 *num3 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
result = result && num3 == NULL;
return wapp_tester_result(result);
}
TestFuncResult test_arena_allocator_temp_end(void) {
wapp_mem_arena_allocator_temp_end(&temp_allocator);
i32 *num1 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
b8 result = num1 != NULL;
i32 *num2 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
result = result && num2 == NULL;
wapp_mem_arena_allocator_destroy(&temp_allocator);
return wapp_tester_result(result);
}

View File

@@ -2,16 +2,66 @@
#include "wapp.h" #include "wapp.h"
#include <stdlib.h> #include <stdlib.h>
// NOTE (Abdelrahman): Cannot query size of Arena here so it's hardcoded. Similarly, since arena
// allocation are aligned to power of 2 boundaries, the number of i32 values needed is hardcoded.
#define TEMP_BUF_SIZE (40 + sizeof(i32) * 8)
wapp_intern u8 temp_buf[TEMP_BUF_SIZE] = {};
wapp_intern Allocator temp_allocator = {};
TestFuncResult test_arena_allocator(void) { TestFuncResult test_arena_allocator(void) {
Allocator allocator = wapp_mem_arena_allocator_init(4096); Allocator allocator = wapp_mem_arena_allocator_init(4096);
b8 result = allocator.obj != nullptr && allocator.alloc != nullptr && b8 result = allocator.obj != nullptr && allocator.alloc != nullptr &&
allocator.alloc_aligned != nullptr && allocator.alloc_aligned != nullptr &&
allocator.realloc != nullptr && allocator.realloc_aligned != nullptr && allocator.realloc != nullptr && allocator.realloc_aligned != nullptr &&
allocator.free == nullptr; allocator.free == nullptr;
void *ptr = wapp_mem_allocator_alloc(&allocator, 20); void *ptr = wapp_mem_allocator_alloc(&allocator, 20);
result = result && (ptr != nullptr); result = result && (ptr != nullptr);
wapp_mem_arena_allocator_destroy(&allocator); wapp_mem_arena_allocator_destroy(&allocator);
return wapp_tester_result(result); return wapp_tester_result(result);
} }
TestFuncResult test_arena_allocator_with_buffer(void) {
u8 buffer[KiB(4)] = {0};
Allocator allocator = wapp_mem_arena_allocator_init_with_buffer(buffer, KiB(4));
b8 result = allocator.obj != NULL && allocator.alloc != NULL &&
allocator.alloc_aligned != NULL &&
allocator.realloc != NULL && allocator.realloc_aligned != NULL &&
allocator.free == NULL;
void *ptr = wapp_mem_allocator_alloc(&allocator, 20);
result = result && (ptr != NULL);
wapp_mem_arena_allocator_destroy(&allocator);
return wapp_tester_result(result);
}
TestFuncResult test_arena_allocator_temp_begin(void) {
temp_allocator = wapp_mem_arena_allocator_init_with_buffer(temp_buf, TEMP_BUF_SIZE);
i32 *num1 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
b8 result = num1 != NULL;
wapp_mem_arena_allocator_temp_begin(&temp_allocator);
i32 *num2 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
result = result && num2 != NULL;
i32 *num3 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
result = result && num3 == NULL;
return wapp_tester_result(result);
}
TestFuncResult test_arena_allocator_temp_end(void) {
wapp_mem_arena_allocator_temp_end(&temp_allocator);
i32 *num1 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
b8 result = num1 != NULL;
i32 *num2 = (i32 *)wapp_mem_allocator_alloc(&temp_allocator, sizeof(i32));
result = result && num2 == NULL;
wapp_mem_arena_allocator_destroy(&temp_allocator);
return wapp_tester_result(result);
}

View File

@@ -4,5 +4,8 @@
#include "wapp.h" #include "wapp.h"
TestFuncResult test_arena_allocator(void); TestFuncResult test_arena_allocator(void);
TestFuncResult test_arena_allocator_with_buffer(void);
TestFuncResult test_arena_allocator_temp_begin(void);
TestFuncResult test_arena_allocator_temp_end(void);
#endif // !TEST_ALLOCATOR_H #endif // !TEST_ALLOCATOR_H

View File

@@ -3,21 +3,34 @@
#include <stdlib.h> #include <stdlib.h>
#define ARENA_CAPACITY KiB(16) #define ARENA_CAPACITY KiB(16)
#define ARENA_BUF_SIZE KiB(4)
// NOTE (Abdelrahman): Cannot query size of Arena here so it's hardcoded. Similarly, since arena
// allocation are aligned to power of 2 boundaries, the number of i32 values needed is hardcoded.
#define TEMP_BUF_SIZE (40 + sizeof(i32) * 8)
wapp_intern Arena *arena = NULL; wapp_intern Arena *arena = NULL;
wapp_intern i32 count = 20; wapp_intern i32 count = 20;
wapp_intern i32 *array = NULL; wapp_intern i32 *array = NULL;
wapp_intern Arena *buf_arena = NULL;
wapp_intern u8 buf[ARENA_BUF_SIZE] = {0};
wapp_intern Arena *temp_arena = NULL;
wapp_intern u8 temp_buf[TEMP_BUF_SIZE] = {0};
TestFuncResult test_arena_init(void) { TestFuncResult test_arena_init_buffer(void) {
b8 result = wapp_mem_arena_init(&arena, ARENA_CAPACITY); b8 result = wapp_mem_arena_init_buffer(&buf_arena, buf, ARENA_BUF_SIZE);
return wapp_tester_result(result);
}
TestFuncResult test_arena_init_allocated(void) {
b8 result = wapp_mem_arena_init_allocated(&arena, ARENA_CAPACITY);
return wapp_tester_result(result); return wapp_tester_result(result);
} }
TestFuncResult test_arena_init_succeeds_when_reserving_very_large_size(void) { TestFuncResult test_arena_init_succeeds_when_reserving_very_large_size(void) {
Arena *large_arena = NULL; Arena *large_arena = NULL;
u64 capacity = GiB(512); u64 capacity = GiB(512);
b8 result = wapp_mem_arena_init(&large_arena, capacity); b8 result = wapp_mem_arena_init_allocated(&large_arena, capacity);
if (result) { if (result) {
wapp_mem_arena_destroy(&large_arena); wapp_mem_arena_destroy(&large_arena);
} }
@@ -25,9 +38,20 @@ TestFuncResult test_arena_init_succeeds_when_reserving_very_large_size(void) {
return wapp_tester_result(result); return wapp_tester_result(result);
} }
TestFuncResult test_arena_alloc_with_buffer(void) {
i32 *arr = (i32 *)wapp_mem_arena_alloc(arena, count * sizeof(i32));
b8 result = arr != NULL;
for (i32 i = 0; i < count; ++i) {
arr[i] = i * 10;
}
return wapp_tester_result(result);
}
TestFuncResult test_arena_alloc_succeeds_when_within_capacity(void) { TestFuncResult test_arena_alloc_succeeds_when_within_capacity(void) {
array = wapp_mem_arena_alloc(arena, count * sizeof(i32)); array = wapp_mem_arena_alloc(arena, count * sizeof(i32));
b8 result = array != NULL; b8 result = array != NULL;
for (i32 i = 0; i < count; ++i) { for (i32 i = 0; i < count; ++i) {
array[i] = i * 10; array[i] = i * 10;
@@ -44,9 +68,9 @@ TestFuncResult test_arena_alloc_fails_when_over_capacity(void) {
} }
TestFuncResult test_arena_realloc_bigger_size(void) { TestFuncResult test_arena_realloc_bigger_size(void) {
u64 old_count = 10; u64 old_count = 10;
u64 new_count = 20; u64 new_count = 20;
i32 *bytes = wapp_mem_arena_alloc(arena, old_count * sizeof(i32)); i32 *bytes = wapp_mem_arena_alloc(arena, old_count * sizeof(i32));
for (u64 i = 0; i < old_count; ++i) { for (u64 i = 0; i < old_count; ++i) {
bytes[i] = (i32)i; bytes[i] = (i32)i;
@@ -67,9 +91,9 @@ TestFuncResult test_arena_realloc_bigger_size(void) {
} }
TestFuncResult test_arena_realloc_smaller_size(void) { TestFuncResult test_arena_realloc_smaller_size(void) {
u64 old_count = 10; u64 old_count = 10;
u64 new_count = 5; u64 new_count = 5;
i32 *bytes = wapp_mem_arena_alloc(arena, old_count * sizeof(i32)); i32 *bytes = wapp_mem_arena_alloc(arena, old_count * sizeof(i32));
for (u64 i = 0; i < old_count; ++i) { for (u64 i = 0; i < old_count; ++i) {
bytes[i] = (i32)i; bytes[i] = (i32)i;
@@ -89,6 +113,32 @@ TestFuncResult test_arena_realloc_smaller_size(void) {
return wapp_tester_result(true); return wapp_tester_result(true);
} }
TestFuncResult test_arena_temp_begin(void) {
b8 result = wapp_mem_arena_init_buffer(&temp_arena, temp_buf, TEMP_BUF_SIZE);
i32 *num1 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
result = result && num1 != NULL;
wapp_mem_arena_temp_begin(temp_arena);
i32 *num2 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
result = result && num2 != NULL;
i32 *num3 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
result = result && num3 == NULL;
return wapp_tester_result(result);
}
TestFuncResult test_arena_temp_end(void) {
wapp_mem_arena_temp_end(temp_arena);
i32 *num1 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
b8 result = num1 != NULL;
i32 *num2 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
result = result && num2 == NULL;
wapp_mem_arena_destroy(&temp_arena);
return wapp_tester_result(result);
}
TestFuncResult test_arena_clear(void) { TestFuncResult test_arena_clear(void) {
wapp_mem_arena_clear(arena); wapp_mem_arena_clear(arena);
b8 result = true; b8 result = true;
@@ -103,7 +153,14 @@ TestFuncResult test_arena_clear(void) {
return wapp_tester_result(result); return wapp_tester_result(result);
} }
TestFuncResult test_arena_destroy(void) { TestFuncResult test_arena_destroy_buffer(void) {
wapp_mem_arena_destroy(&buf_arena);
b8 result = buf_arena == NULL;
return wapp_tester_result(result);
}
TestFuncResult test_arena_destroy_allocated(void) {
wapp_mem_arena_destroy(&arena); wapp_mem_arena_destroy(&arena);
b8 result = arena == NULL; b8 result = arena == NULL;

View File

@@ -3,21 +3,34 @@
#include <stdlib.h> #include <stdlib.h>
#define ARENA_CAPACITY KiB(16) #define ARENA_CAPACITY KiB(16)
#define ARENA_BUF_SIZE KiB(4)
// NOTE (Abdelrahman): Cannot query size of Arena here so it's hardcoded. Similarly, since arena
// allocation are aligned to power of 2 boundaries, the number of i32 values needed is hardcoded.
#define TEMP_BUF_SIZE (40 + sizeof(i32) * 8)
wapp_intern Arena *arena = nullptr; wapp_intern Arena *arena = NULL;
wapp_intern i32 count = 20; wapp_intern i32 count = 20;
wapp_intern i32 *array = nullptr; wapp_intern i32 *array = NULL;
wapp_intern Arena *buf_arena = NULL;
wapp_intern u8 buf[ARENA_BUF_SIZE] = {};
wapp_intern Arena *temp_arena = NULL;
wapp_intern u8 temp_buf[TEMP_BUF_SIZE] = {};
TestFuncResult test_arena_init(void) { TestFuncResult test_arena_init_buffer(void) {
b8 result = wapp_mem_arena_init(&arena, ARENA_CAPACITY); b8 result = wapp_mem_arena_init_buffer(&buf_arena, buf, ARENA_BUF_SIZE);
return wapp_tester_result(result);
}
TestFuncResult test_arena_init_allocated(void) {
b8 result = wapp_mem_arena_init_allocated(&arena, ARENA_CAPACITY);
return wapp_tester_result(result); return wapp_tester_result(result);
} }
TestFuncResult test_arena_init_succeeds_when_reserving_very_large_size(void) { TestFuncResult test_arena_init_succeeds_when_reserving_very_large_size(void) {
Arena *large_arena = nullptr; Arena *large_arena = nullptr;
u64 capacity = GiB(512); u64 capacity = GiB(512);
b8 result = wapp_mem_arena_init(&large_arena, capacity); b8 result = wapp_mem_arena_init_allocated(&large_arena, capacity);
if (result) { if (result) {
wapp_mem_arena_destroy(&large_arena); wapp_mem_arena_destroy(&large_arena);
} }
@@ -25,9 +38,20 @@ TestFuncResult test_arena_init_succeeds_when_reserving_very_large_size(void) {
return wapp_tester_result(result); return wapp_tester_result(result);
} }
TestFuncResult test_arena_alloc_with_buffer(void) {
i32 *arr = (i32 *)wapp_mem_arena_alloc(arena, count * sizeof(i32));
b8 result = arr != NULL;
for (i32 i = 0; i < count; ++i) {
arr[i] = i * 10;
}
return wapp_tester_result(result);
}
TestFuncResult test_arena_alloc_succeeds_when_within_capacity(void) { TestFuncResult test_arena_alloc_succeeds_when_within_capacity(void) {
array = (i32 *)wapp_mem_arena_alloc(arena, count * sizeof(i32)); array = (i32 *)wapp_mem_arena_alloc(arena, count * sizeof(i32));
b8 result = array != nullptr; b8 result = array != nullptr;
for (i32 i = 0; i < count; ++i) { for (i32 i = 0; i < count; ++i) {
array[i] = i * 10; array[i] = i * 10;
@@ -44,9 +68,9 @@ TestFuncResult test_arena_alloc_fails_when_over_capacity(void) {
} }
TestFuncResult test_arena_realloc_bigger_size(void) { TestFuncResult test_arena_realloc_bigger_size(void) {
u64 old_count = 10; u64 old_count = 10;
u64 new_count = 20; u64 new_count = 20;
i32 *bytes = (i32 *)wapp_mem_arena_alloc(arena, old_count * sizeof(i32)); i32 *bytes = (i32 *)wapp_mem_arena_alloc(arena, old_count * sizeof(i32));
for (u64 i = 0; i < old_count; ++i) { for (u64 i = 0; i < old_count; ++i) {
bytes[i] = (i32)i; bytes[i] = (i32)i;
@@ -67,9 +91,9 @@ TestFuncResult test_arena_realloc_bigger_size(void) {
} }
TestFuncResult test_arena_realloc_smaller_size(void) { TestFuncResult test_arena_realloc_smaller_size(void) {
u64 old_count = 10; u64 old_count = 10;
u64 new_count = 5; u64 new_count = 5;
i32 *bytes = (i32 *)wapp_mem_arena_alloc(arena, old_count * sizeof(i32)); i32 *bytes = (i32 *)wapp_mem_arena_alloc(arena, old_count * sizeof(i32));
for (u64 i = 0; i < old_count; ++i) { for (u64 i = 0; i < old_count; ++i) {
bytes[i] = (i32)i; bytes[i] = (i32)i;
@@ -89,6 +113,32 @@ TestFuncResult test_arena_realloc_smaller_size(void) {
return wapp_tester_result(true); return wapp_tester_result(true);
} }
TestFuncResult test_arena_temp_begin(void) {
b8 result = wapp_mem_arena_init_buffer(&temp_arena, temp_buf, TEMP_BUF_SIZE);
i32 *num1 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
result = result && num1 != NULL;
wapp_mem_arena_temp_begin(temp_arena);
i32 *num2 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
result = result && num2 != NULL;
i32 *num3 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
result = result && num3 == NULL;
return wapp_tester_result(result);
}
TestFuncResult test_arena_temp_end(void) {
wapp_mem_arena_temp_end(temp_arena);
i32 *num1 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
b8 result = num1 != NULL;
i32 *num2 = (i32 *)wapp_mem_arena_alloc(temp_arena, sizeof(i32));
result = result && num2 == NULL;
wapp_mem_arena_destroy(&temp_arena);
return wapp_tester_result(result);
}
TestFuncResult test_arena_clear(void) { TestFuncResult test_arena_clear(void) {
wapp_mem_arena_clear(arena); wapp_mem_arena_clear(arena);
b8 result = true; b8 result = true;
@@ -103,7 +153,14 @@ TestFuncResult test_arena_clear(void) {
return wapp_tester_result(result); return wapp_tester_result(result);
} }
TestFuncResult test_arena_destroy(void) { TestFuncResult test_arena_destroy_buffer(void) {
wapp_mem_arena_destroy(&buf_arena);
b8 result = buf_arena == NULL;
return wapp_tester_result(result);
}
TestFuncResult test_arena_destroy_allocated(void) {
wapp_mem_arena_destroy(&arena); wapp_mem_arena_destroy(&arena);
b8 result = arena == nullptr; b8 result = arena == nullptr;

View File

@@ -3,13 +3,18 @@
#include "wapp.h" #include "wapp.h"
TestFuncResult test_arena_init(void); TestFuncResult test_arena_init_buffer(void);
TestFuncResult test_arena_init_allocated(void);
TestFuncResult test_arena_init_succeeds_when_reserving_very_large_size(void); TestFuncResult test_arena_init_succeeds_when_reserving_very_large_size(void);
TestFuncResult test_arena_alloc_with_buffer(void);
TestFuncResult test_arena_alloc_succeeds_when_within_capacity(void); TestFuncResult test_arena_alloc_succeeds_when_within_capacity(void);
TestFuncResult test_arena_alloc_fails_when_over_capacity(void); TestFuncResult test_arena_alloc_fails_when_over_capacity(void);
TestFuncResult test_arena_realloc_bigger_size(void); TestFuncResult test_arena_realloc_bigger_size(void);
TestFuncResult test_arena_realloc_smaller_size(void); TestFuncResult test_arena_realloc_smaller_size(void);
TestFuncResult test_arena_clear(void); TestFuncResult test_arena_clear(void);
TestFuncResult test_arena_destroy(void); TestFuncResult test_arena_temp_begin(void);
TestFuncResult test_arena_temp_end(void);
TestFuncResult test_arena_destroy_buffer(void);
TestFuncResult test_arena_destroy_allocated(void);
#endif // !TEST_ARENA_H #endif // !TEST_ARENA_H

View File

@@ -4,16 +4,16 @@
TestFuncResult test_i32_array(void) { TestFuncResult test_i32_array(void) {
b8 result; b8 result;
I32Array array = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6, 7); I32Array array = wapp_array(i32, 1, 2, 3, 4, 5, 6, 7);
result = array.count == 7 && array.capacity == 16; result = wapp_array_count(array) == 7 && wapp_array_capacity(array) == 16;
i32 *item; i32 *item;
u64 count = array.count; u64 count = wapp_array_count(array);
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
item = wapp_array_get(i32, &array, index); item = wapp_array_get(i32, array, index);
result = result && item && *item == (i32)(index + 1); result = result && item && *item == (i32)(index + 1);
++index; ++index;
running = index < count; running = index < count;
@@ -25,11 +25,11 @@ TestFuncResult test_i32_array(void) {
TestFuncResult test_i32_array_with_capacity(void) { TestFuncResult test_i32_array_with_capacity(void) {
b8 result; b8 result;
I32Array array1 = wapp_array_with_capacity(i32, I32Array, 64, false); I32Array array1 = wapp_array_with_capacity(i32, 64, ARRAY_INIT_NONE);
result = array1.count == 0 && array1.capacity == 64; result = wapp_array_count(array1) == 0 && wapp_array_capacity(array1) == 64;
I32Array array2 = wapp_array_with_capacity(i32, I32Array, 64, true); I32Array array2 = wapp_array_with_capacity(i32, 64, ARRAY_INIT_FILLED);
result = array2.count == 64 && array2.capacity == 64; result = wapp_array_count(array2) == 64 && wapp_array_capacity(array2) == 64;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -37,15 +37,15 @@ TestFuncResult test_i32_array_with_capacity(void) {
TestFuncResult test_i32_array_get(void) { TestFuncResult test_i32_array_get(void) {
b8 result = true; b8 result = true;
I32Array array = wapp_array(i32, I32Array, 0, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
i32 *item; i32 *item;
u64 count = array.count; u64 count = wapp_array_count(array);
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
item = wapp_array_get(i32, &array, index); item = wapp_array_get(i32, array, index);
result = result && item && *item == (i32)index; result = result && item && *item == (i32)index;
++index; ++index;
running = index < count; running = index < count;
@@ -57,17 +57,17 @@ TestFuncResult test_i32_array_get(void) {
TestFuncResult test_i32_array_set(void) { TestFuncResult test_i32_array_set(void) {
b8 result = true; b8 result = true;
I32Array array = wapp_array(i32, I32Array, 0, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
i32 *item; i32 *item;
u64 count = array.count; u64 count = wapp_array_count(array);
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
i32 num = (i32)(index * 2); i32 num = (i32)(index * 2);
wapp_array_set(i32, &array, index, &num); wapp_array_set(i32, array, index, &num);
item = wapp_array_get(i32, &array, index); item = wapp_array_get(i32, array, index);
result = result && item && *item == (i32)(index * 2); result = result && item && *item == (i32)(index * 2);
++index; ++index;
running = index < count; running = index < count;
@@ -79,17 +79,17 @@ TestFuncResult test_i32_array_set(void) {
TestFuncResult test_i32_array_append_capped(void) { TestFuncResult test_i32_array_append_capped(void) {
b8 result; b8 result;
I32Array array = wapp_array_with_capacity(i32, I32Array, 64, false); I32Array array = wapp_array_with_capacity(i32, 64, ARRAY_INIT_NONE);
wapp_array_append_capped(i32, &array, &((i32){10})); wapp_array_append_capped(i32, array, &((i32){10}));
result = array.count == 1; result = wapp_array_count(array) == 1;
i32 *item = wapp_array_get(i32, &array, 0); i32 *item = wapp_array_get(i32, array, 0);
result = result && item && *item == 10; result = result && item && *item == 10;
array = wapp_array(i32, I32Array, 1); array = wapp_array(i32, 1);
wapp_array_append_capped(i32, &array, &((i32){10})); wapp_array_append_capped(i32, array, &((i32){10}));
result = result && array.count == 2; result = result && wapp_array_count(array) == 2;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -97,14 +97,14 @@ TestFuncResult test_i32_array_append_capped(void) {
TestFuncResult test_i32_array_extend_capped(void) { TestFuncResult test_i32_array_extend_capped(void) {
b8 result; b8 result;
I32Array array1 = wapp_array(i32, I32Array, 1, 2, 3, 4); I32Array array1 = wapp_array(i32, 1, 2, 3, 4);
I32Array array2 = wapp_array(i32, I32Array, 10, 20); I32Array array2 = wapp_array(i32, 10, 20);
result = array1.count == 4 && array2.count == 2; result = wapp_array_count(array1) == 4 && wapp_array_count(array2) == 2;
wapp_array_extend_capped(i32, &array1, &array2); wapp_array_extend_capped(i32, array1, array2);
result = result && array1.count == 6; result = result && wapp_array_count(array1) == 6;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -112,31 +112,31 @@ TestFuncResult test_i32_array_extend_capped(void) {
TestFuncResult test_i32_array_copy_capped(void) { TestFuncResult test_i32_array_copy_capped(void) {
b8 result; b8 result;
I32Array src = wapp_array(i32, I32Array, 1, 2, 3, 4, 5); I32Array src = wapp_array(i32, 1, 2, 3, 4, 5);
I32Array dst1 = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6); I32Array dst1 = wapp_array(i32, 1, 2, 3, 4, 5, 6);
I32Array dst2 = wapp_array(i32, I32Array, 1, 2); I32Array dst2 = wapp_array(i32, 1, 2);
u64 expected_count = 5; u64 expected_count = 5;
wapp_array_copy_capped(i32, &dst1, &src); wapp_array_copy_capped(i32, dst1, src);
result = dst1.count == expected_count; result = wapp_array_count(dst1) == expected_count;
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
result = result && *wapp_array_get(i32, &src, index) == *wapp_array_get(i32, &dst1, index); result = result && *wapp_array_get(i32, src, index) == *wapp_array_get(i32, dst1, index);
++index; ++index;
running = index < expected_count; running = index < expected_count;
} }
expected_count = 4; expected_count = 4;
wapp_array_copy_capped(i32, &dst2, &src); wapp_array_copy_capped(i32, dst2, src);
result = result && dst2.count == expected_count; result = result && wapp_array_count(dst2) == expected_count;
index = 0; index = 0;
running = true; running = true;
while (running) { while (running) {
result = result && *wapp_array_get(i32, &src, index) == *wapp_array_get(i32, &dst2, index); result = result && *wapp_array_get(i32, src, index) == *wapp_array_get(i32, dst2, index);
++index; ++index;
running = index < expected_count; running = index < expected_count;
@@ -148,11 +148,11 @@ TestFuncResult test_i32_array_copy_capped(void) {
TestFuncResult test_i32_array_alloc_capacity(void) { TestFuncResult test_i32_array_alloc_capacity(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MiB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MiB(4));
u64 capacity = 32; u64 capacity = 32;
I32Array *array = wapp_array_alloc_capacity(i32, I32Array, &allocator, capacity, false); I32Array array = wapp_array_alloc_capacity(i32, &allocator, capacity, ARRAY_INIT_NONE);
result = array && array->capacity == capacity; result = array && wapp_array_capacity(array) == capacity;
wapp_mem_arena_allocator_destroy(&allocator); wapp_mem_arena_allocator_destroy(&allocator);
@@ -162,24 +162,24 @@ TestFuncResult test_i32_array_alloc_capacity(void) {
TestFuncResult test_i32_array_append_alloc(void) { TestFuncResult test_i32_array_append_alloc(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MiB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MiB(4));
I32Array array1 = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array1 = wapp_array(i32, 1, 2, 3, 4, 5, 6, 7, 8);
I32Array array2 = wapp_array(i32, I32Array, 1, 2); I32Array array2 = wapp_array(i32, 1, 2);
I32Array *arr_ptr = wapp_array_append_alloc(i32, I32Array, &allocator, &array1, &((i32){10})); I32Array arr_ptr = wapp_array_append_alloc(i32, &allocator, array1, &((i32){10}), ARRAY_INIT_NONE);
result = arr_ptr == &array1; result = arr_ptr == array1;
u64 count = 4; u64 count = 4;
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
i32 num = (i32)index; i32 num = (i32)index;
arr_ptr = wapp_array_append_alloc(i32, I32Array, &allocator, &array2, &num); arr_ptr = wapp_array_append_alloc(i32, &allocator, array2, &num, ARRAY_INIT_NONE);
++index; ++index;
running = index < count; running = index < count;
} }
result = result && arr_ptr != &array2; result = result && arr_ptr != array2;
wapp_mem_arena_allocator_destroy(&allocator); wapp_mem_arena_allocator_destroy(&allocator);
@@ -189,16 +189,16 @@ TestFuncResult test_i32_array_append_alloc(void) {
TestFuncResult test_i32_array_extend_alloc(void) { TestFuncResult test_i32_array_extend_alloc(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MiB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MiB(4));
I32Array array1 = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array1 = wapp_array(i32, 1, 2, 3, 4, 5, 6, 7, 8);
I32Array array2 = wapp_array(i32, I32Array, 1, 2); I32Array array2 = wapp_array(i32, 1, 2);
I32Array array3 = wapp_array(i32, I32Array, 1, 2, 3, 4); I32Array array3 = wapp_array(i32, 1, 2, 3, 4);
I32Array *arr_ptr = wapp_array_extend_alloc(i32, I32Array, &allocator, &array1, &array3); I32Array arr_ptr = wapp_array_extend_alloc(i32, &allocator, array1, array3, ARRAY_INIT_NONE);
result = arr_ptr == &array1; result = arr_ptr == array1;
arr_ptr = wapp_array_extend_alloc(i32, I32Array, &allocator, &array2, &array3); arr_ptr = wapp_array_extend_alloc(i32, &allocator, array2, array3, ARRAY_INIT_NONE);
result = result && arr_ptr != &array2; result = result && arr_ptr != array2;
wapp_mem_arena_allocator_destroy(&allocator); wapp_mem_arena_allocator_destroy(&allocator);
@@ -208,33 +208,33 @@ TestFuncResult test_i32_array_extend_alloc(void) {
TestFuncResult test_i32_array_copy_alloc(void) { TestFuncResult test_i32_array_copy_alloc(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MiB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MiB(4));
I32Array src = wapp_array(i32, I32Array, 1, 2, 3, 4, 5); I32Array src = wapp_array(i32, 1, 2, 3, 4, 5);
I32Array dst1 = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6); I32Array dst1 = wapp_array(i32, 1, 2, 3, 4, 5, 6);
I32Array dst2 = wapp_array(i32, I32Array, 1, 2); I32Array dst2 = wapp_array(i32, 1, 2);
I32Array *array_ptr = NULL; I32Array array = NULL;
u64 expected_count = 5; u64 expected_count = 5;
array_ptr = wapp_array_copy_alloc(i32, I32Array, &allocator, &dst1, &src); array = wapp_array_copy_alloc(i32, &allocator, dst1, src, ARRAY_INIT_NONE);
result = array_ptr->count == expected_count && array_ptr == &dst1; result = wapp_array_count(array) == expected_count && array == dst1;
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
result = result && *wapp_array_get(i32, &src, index) == *wapp_array_get(i32, array_ptr, index); result = result && *wapp_array_get(i32, src, index) == *wapp_array_get(i32, array, index);
++index; ++index;
running = index < expected_count; running = index < expected_count;
} }
expected_count = 5; expected_count = 5;
array_ptr = wapp_array_copy_alloc(i32, I32Array, &allocator, &dst2, &src); array = wapp_array_copy_alloc(i32, &allocator, dst2, src, ARRAY_INIT_NONE);
result = result && array_ptr->count == expected_count && array_ptr != &dst2; result = result && wapp_array_count(array) == expected_count && array != dst2;
index = 0; index = 0;
running = true; running = true;
while (running) { while (running) {
result = result && *wapp_array_get(i32, &src, index) == *wapp_array_get(i32, array_ptr, index); result = result && *wapp_array_get(i32, src, index) == *wapp_array_get(i32, array, index);
++index; ++index;
running = index < expected_count; running = index < expected_count;
@@ -248,11 +248,11 @@ TestFuncResult test_i32_array_copy_alloc(void) {
TestFuncResult test_i32_array_pop(void) { TestFuncResult test_i32_array_pop(void) {
b8 result; b8 result;
I32Array array1 = wapp_array(i32, I32Array, 0, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array1 = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
I32Array array2 = wapp_array_with_capacity(i32, I32Array, 32, false); I32Array array2 = wapp_array_with_capacity(i32, 32, ARRAY_INIT_NONE);
i32 item1 = wapp_array_pop(i32, &array1); i32 item1 = wapp_array_pop(i32, array1);
i32 item2 = wapp_array_pop(i32, &array2); i32 item2 = wapp_array_pop(i32, array2);
result = item1 == 8 && item2 == 0; result = item1 == 8 && item2 == 0;
@@ -262,12 +262,12 @@ TestFuncResult test_i32_array_pop(void) {
TestFuncResult test_i32_array_clear(void) { TestFuncResult test_i32_array_clear(void) {
b8 result; b8 result;
I32Array array = wapp_array(i32, I32Array, 0, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
result = array.count == 9; result = wapp_array_count(array) == 9;
wapp_array_clear(i32, &array); wapp_array_clear(i32, array);
result = result && array.count == 0; result = result && wapp_array_count(array) == 0;
return wapp_tester_result(result); return wapp_tester_result(result);
} }

View File

@@ -4,16 +4,16 @@
TestFuncResult test_i32_array(void) { TestFuncResult test_i32_array(void) {
b8 result; b8 result;
I32Array array = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6, 7); I32Array array = wapp_array(i32, 1, 2, 3, 4, 5, 6, 7);
result = array.count == 7 && array.capacity == 16; result = wapp_array_count(array) == 7 && wapp_array_capacity(array) == 16;
i32 *item; i32 *item;
u64 count = array.count; u64 count = wapp_array_count(array);
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
item = wapp_array_get(i32, &array, index); item = wapp_array_get(i32, array, index);
result = result && item && (*item == (i32)(index + 1)); result = result && item && (*item == (i32)(index + 1));
++index; ++index;
running = index < count; running = index < count;
@@ -25,11 +25,11 @@ TestFuncResult test_i32_array(void) {
TestFuncResult test_i32_array_with_capacity(void) { TestFuncResult test_i32_array_with_capacity(void) {
b8 result; b8 result;
I32Array array1 = wapp_array_with_capacity(i32, I32Array, 64, false); I32Array array1 = wapp_array_with_capacity(i32, 64, ARRAY_INIT_NONE);
result = array1.count == 0 && array1.capacity == 64; result = wapp_array_count(array1) == 0 && wapp_array_capacity(array1) == 64;
I32Array array2 = wapp_array_with_capacity(i32, I32Array, 64, true); I32Array array2 = wapp_array_with_capacity(i32, 64, ARRAY_INIT_FILLED);
result = array2.count == 64 && array2.capacity == 64; result = wapp_array_count(array2) == 64 && wapp_array_capacity(array2) == 64;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -37,15 +37,15 @@ TestFuncResult test_i32_array_with_capacity(void) {
TestFuncResult test_i32_array_get(void) { TestFuncResult test_i32_array_get(void) {
b8 result = true; b8 result = true;
I32Array array = wapp_array(i32, I32Array, 0, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
i32 *item; i32 *item;
u64 count = array.count; u64 count = wapp_array_count(array);
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
item = wapp_array_get(i32, &array, index); item = wapp_array_get(i32, array, index);
result = result && item && (*item == (i32)index); result = result && item && (*item == (i32)index);
++index; ++index;
running = index < count; running = index < count;
@@ -57,17 +57,17 @@ TestFuncResult test_i32_array_get(void) {
TestFuncResult test_i32_array_set(void) { TestFuncResult test_i32_array_set(void) {
b8 result = true; b8 result = true;
I32Array array = wapp_array(i32, I32Array, 0, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
i32 *item; i32 *item;
u64 count = array.count; u64 count = wapp_array_count(array);
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
i32 num = (i32)(index * 2); i32 num = (i32)(index * 2);
wapp_array_set(i32, &array, index, &num); wapp_array_set(i32, array, index, &num);
item = wapp_array_get(i32, &array, index); item = wapp_array_get(i32, array, index);
result = result && item && (*item == (i32)(index * 2)); result = result && item && (*item == (i32)(index * 2));
++index; ++index;
running = index < count; running = index < count;
@@ -79,19 +79,19 @@ TestFuncResult test_i32_array_set(void) {
TestFuncResult test_i32_array_append_capped(void) { TestFuncResult test_i32_array_append_capped(void) {
b8 result; b8 result;
I32Array array = wapp_array_with_capacity(i32, I32Array, 64, false); I32Array array = wapp_array_with_capacity(i32, 64, ARRAY_INIT_NONE);
i32 item1 = 10; i32 item1 = 10;
wapp_array_append_capped(i32, &array, &item1); wapp_array_append_capped(i32, array, &item1);
result = array.count == 1; result = wapp_array_count(array) == 1;
i32 *item = wapp_array_get(i32, &array, 0); i32 *item = wapp_array_get(i32, array, 0);
result = result && item && *item == 10; result = result && item && *item == 10;
array = wapp_array(i32, I32Array, 1); array = wapp_array(i32, 1);
i32 item2 = 10; i32 item2 = 10;
wapp_array_append_capped(i32, &array, &item2); wapp_array_append_capped(i32, array, &item2);
result = result && array.count == 2; result = result && wapp_array_count(array) == 2;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -99,14 +99,14 @@ TestFuncResult test_i32_array_append_capped(void) {
TestFuncResult test_i32_array_extend_capped(void) { TestFuncResult test_i32_array_extend_capped(void) {
b8 result; b8 result;
I32Array array1 = wapp_array(i32, I32Array, 1, 2, 3, 4); I32Array array1 = wapp_array(i32, 1, 2, 3, 4);
I32Array array2 = wapp_array(i32, I32Array, 10, 20); I32Array array2 = wapp_array(i32, 10, 20);
result = array1.count == 4 && array2.count == 2; result = wapp_array_count(array1) == 4 && wapp_array_count(array2) == 2;
wapp_array_extend_capped(i32, &array1, &array2); wapp_array_extend_capped(i32, array1, array2);
result = result && array1.count == 6; result = result && wapp_array_count(array1) == 6;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -114,31 +114,31 @@ TestFuncResult test_i32_array_extend_capped(void) {
TestFuncResult test_i32_array_copy_capped(void) { TestFuncResult test_i32_array_copy_capped(void) {
b8 result; b8 result;
I32Array src = wapp_array(i32, I32Array, 1, 2, 3, 4, 5); I32Array src = wapp_array(i32, 1, 2, 3, 4, 5);
I32Array dst1 = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6); I32Array dst1 = wapp_array(i32, 1, 2, 3, 4, 5, 6);
I32Array dst2 = wapp_array(i32, I32Array, 1, 2); I32Array dst2 = wapp_array(i32, 1, 2);
u64 expected_count = 5; u64 expected_count = 5;
wapp_array_copy_capped(i32, &dst1, &src); wapp_array_copy_capped(i32, dst1, src);
result = dst1.count == expected_count; result = wapp_array_count(dst1) == expected_count;
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
result = result && (*wapp_array_get(i32, &src, index) == *wapp_array_get(i32, &dst1, index)); result = result && (*wapp_array_get(i32, src, index) == *wapp_array_get(i32, dst1, index));
++index; ++index;
running = index < expected_count; running = index < expected_count;
} }
expected_count = 4; expected_count = 4;
wapp_array_copy_capped(i32, &dst2, &src); wapp_array_copy_capped(i32, dst2, src);
result = result && dst2.count == expected_count; result = result && wapp_array_count(dst2) == expected_count;
index = 0; index = 0;
running = true; running = true;
while (running) { while (running) {
result = result && (*wapp_array_get(i32, &src, index) == *wapp_array_get(i32, &dst2, index)); result = result && (*wapp_array_get(i32, src, index) == *wapp_array_get(i32, dst2, index));
++index; ++index;
running = index < expected_count; running = index < expected_count;
@@ -150,11 +150,11 @@ TestFuncResult test_i32_array_copy_capped(void) {
TestFuncResult test_i32_array_alloc_capacity(void) { TestFuncResult test_i32_array_alloc_capacity(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MiB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MiB(4));
u64 capacity = 32; u64 capacity = 32;
I32Array *array = wapp_array_alloc_capacity(i32, I32Array, &allocator, capacity, false); I32Array array = wapp_array_alloc_capacity(i32, &allocator, capacity, ARRAY_INIT_NONE);
result = array && array->capacity == capacity; result = array && wapp_array_capacity(array) == capacity;
wapp_mem_arena_allocator_destroy(&allocator); wapp_mem_arena_allocator_destroy(&allocator);
@@ -164,25 +164,25 @@ TestFuncResult test_i32_array_alloc_capacity(void) {
TestFuncResult test_i32_array_append_alloc(void) { TestFuncResult test_i32_array_append_alloc(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MiB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MiB(4));
I32Array array1 = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array1 = wapp_array(i32, 1, 2, 3, 4, 5, 6, 7, 8);
I32Array array2 = wapp_array(i32, I32Array, 1, 2); I32Array array2 = wapp_array(i32, 1, 2);
i32 num = 10; i32 num = 10;
I32Array *arr_ptr = wapp_array_append_alloc(i32, I32Array, &allocator, &array1, &num); I32Array arr_ptr = wapp_array_append_alloc(i32, &allocator, array1, &num, ARRAY_INIT_NONE);
result = arr_ptr == &array1; result = arr_ptr == array1;
u64 count = 4; u64 count = 4;
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
num = (i32)index; num = (i32)index;
arr_ptr = wapp_array_append_alloc(i32, I32Array, &allocator, &array2, &num); arr_ptr = wapp_array_append_alloc(i32, &allocator, array2, &num, ARRAY_INIT_NONE);
++index; ++index;
running = index < count; running = index < count;
} }
result = result && arr_ptr != &array2; result = result && arr_ptr != array2;
wapp_mem_arena_allocator_destroy(&allocator); wapp_mem_arena_allocator_destroy(&allocator);
@@ -192,16 +192,16 @@ TestFuncResult test_i32_array_append_alloc(void) {
TestFuncResult test_i32_array_extend_alloc(void) { TestFuncResult test_i32_array_extend_alloc(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MiB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MiB(4));
I32Array array1 = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array1 = wapp_array(i32, 1, 2, 3, 4, 5, 6, 7, 8);
I32Array array2 = wapp_array(i32, I32Array, 1, 2); I32Array array2 = wapp_array(i32, 1, 2);
I32Array array3 = wapp_array(i32, I32Array, 1, 2, 3, 4); I32Array array3 = wapp_array(i32, 1, 2, 3, 4);
I32Array *arr_ptr = wapp_array_extend_alloc(i32, I32Array, &allocator, &array1, &array3); I32Array array = wapp_array_extend_alloc(i32, &allocator, array1, array3, ARRAY_INIT_NONE);
result = arr_ptr == &array1; result = array == array1;
arr_ptr = wapp_array_extend_alloc(i32, I32Array, &allocator, &array2, &array3); array = wapp_array_extend_alloc(i32, &allocator, array2, array3, ARRAY_INIT_NONE);
result = result && arr_ptr != &array2; result = result && array != array2;
wapp_mem_arena_allocator_destroy(&allocator); wapp_mem_arena_allocator_destroy(&allocator);
@@ -211,33 +211,33 @@ TestFuncResult test_i32_array_extend_alloc(void) {
TestFuncResult test_i32_array_copy_alloc(void) { TestFuncResult test_i32_array_copy_alloc(void) {
b8 result; b8 result;
Allocator allocator = wapp_mem_arena_allocator_init(MiB(4)); Allocator allocator = wapp_mem_arena_allocator_init(MiB(4));
I32Array src = wapp_array(i32, I32Array, 1, 2, 3, 4, 5); I32Array src = wapp_array(i32, 1, 2, 3, 4, 5);
I32Array dst1 = wapp_array(i32, I32Array, 1, 2, 3, 4, 5, 6); I32Array dst1 = wapp_array(i32, 1, 2, 3, 4, 5, 6);
I32Array dst2 = wapp_array(i32, I32Array, 1, 2); I32Array dst2 = wapp_array(i32, 1, 2);
I32Array *array_ptr = nullptr; I32Array array = nullptr;
u64 expected_count = 5; u64 expected_count = 5;
array_ptr = wapp_array_copy_alloc(i32, I32Array, &allocator, &dst1, &src); array = wapp_array_copy_alloc(i32, &allocator, dst1, src, ARRAY_INIT_NONE);
result = array_ptr->count == expected_count && array_ptr == &dst1; result = wapp_array_count(array) == expected_count && array == dst1;
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
result = result && (*wapp_array_get(i32, &src, index) == *wapp_array_get(i32, array_ptr, index)); result = result && (*wapp_array_get(i32, src, index) == *wapp_array_get(i32, array, index));
++index; ++index;
running = index < expected_count; running = index < expected_count;
} }
expected_count = 5; expected_count = 5;
array_ptr = wapp_array_copy_alloc(i32, I32Array, &allocator, &dst2, &src); array = wapp_array_copy_alloc(i32, &allocator, dst2, src, ARRAY_INIT_NONE);
result = result && array_ptr->count == expected_count && array_ptr != &dst2; result = result && wapp_array_count(array) == expected_count && array != dst2;
index = 0; index = 0;
running = true; running = true;
while (running) { while (running) {
result = result && (*wapp_array_get(i32, &src, index) == *wapp_array_get(i32, array_ptr, index)); result = result && (*wapp_array_get(i32, src, index) == *wapp_array_get(i32, array, index));
++index; ++index;
running = index < expected_count; running = index < expected_count;
@@ -251,12 +251,12 @@ TestFuncResult test_i32_array_copy_alloc(void) {
TestFuncResult test_i32_array_clear(void) { TestFuncResult test_i32_array_clear(void) {
b8 result; b8 result;
I32Array array = wapp_array(i32, I32Array, 0, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
result = array.count == 9; result = wapp_array_count(array) == 9;
wapp_array_clear(i32, &array); wapp_array_clear(i32, array);
result = result && array.count == 0; result = result && wapp_array_count(array) == 0;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -264,11 +264,11 @@ TestFuncResult test_i32_array_clear(void) {
TestFuncResult test_i32_array_pop(void) { TestFuncResult test_i32_array_pop(void) {
b8 result; b8 result;
I32Array array1 = wapp_array(i32, I32Array, 0, 1, 2, 3, 4, 5, 6, 7, 8); I32Array array1 = wapp_array(i32, 0, 1, 2, 3, 4, 5, 6, 7, 8);
I32Array array2 = wapp_array_with_capacity(i32, I32Array, 32, false); I32Array array2 = wapp_array_with_capacity(i32, 32, ARRAY_INIT_NONE);
i32 item1 = wapp_array_pop(i32, &array1); i32 item1 = wapp_array_pop(i32, array1);
i32 item2 = wapp_array_pop(i32, &array2); i32 item2 = wapp_array_pop(i32, array2);
result = item1 == 8 && item2 == 0; result = item1 == 8 && item2 == 0;

View File

@@ -6,16 +6,16 @@ TestFuncResult test_str8_array(void) {
b8 result; b8 result;
Str8 expected[] = {wapp_str8_lit("Hello"), wapp_str8_lit("Hi"), wapp_str8_lit("Bye")}; Str8 expected[] = {wapp_str8_lit("Hello"), wapp_str8_lit("Hi"), wapp_str8_lit("Bye")};
Str8Array array = wapp_array(Str8, Str8Array, wapp_str8_lit("Hello"), wapp_str8_lit("Hi"), wapp_str8_lit("Bye")); Str8Array array = wapp_array(Str8, wapp_str8_lit("Hello"), wapp_str8_lit("Hi"), wapp_str8_lit("Bye"));
result = array.count == 3 && array.capacity == 8; result = wapp_array_count(array) == 3 && wapp_array_capacity(array) == 8;
Str8 *item; Str8 *item;
u64 count = array.count; u64 count = wapp_array_count(array);
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
item = wapp_array_get(Str8, &array, index); item = wapp_array_get(Str8, array, index);
result = result && item && (wapp_str8_equal(item, &expected[index])); result = result && item && (wapp_str8_equal(item, &expected[index]));
++index; ++index;
running = index < count; running = index < count;

View File

@@ -7,20 +7,20 @@ TestFuncResult test_str8_array(void) {
Str8 expected[] = {wapp_str8_lit("Hello"), wapp_str8_lit("Hi"), wapp_str8_lit("Bye")}; Str8 expected[] = {wapp_str8_lit("Hello"), wapp_str8_lit("Hi"), wapp_str8_lit("Bye")};
Str8 str1 = wapp_str8_lit("Hello"); Str8 str1 = wapp_str8_lit("Hello");
Str8 str2 = wapp_str8_lit("Hi"); Str8 str2 = wapp_str8_lit("Hi");
Str8 str3 = wapp_str8_lit("Bye"); Str8 str3 = wapp_str8_lit("Bye");
Str8Array array = wapp_array(Str8, Str8Array, str1, str2, str3); Str8Array array = wapp_array(Str8, str1, str2, str3);
result = array.count == 3 && array.capacity == 8; result = wapp_array_count(array) == 3 && wapp_array_capacity(array) == 8;
Str8 *item; Str8 *item;
u64 count = array.count; u64 count = wapp_array_count(array);
u64 index = 0; u64 index = 0;
b8 running = true; b8 running = true;
while (running) { while (running) {
item = wapp_array_get(Str8, &array, index); item = wapp_array_get(Str8, array, index);
result = result && item && (wapp_str8_equal(item, &expected[index])); result = result && item && (wapp_str8_equal(item, &expected[index]));
++index; ++index;
running = index < count; running = index < count;

View File

@@ -3,29 +3,29 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#define MAIN_BUF_SIZE 4096 #define MAIN_BUF_SIZE 4096
#define TMP_BUF_SIZE 1024 #define TMP_BUF_SIZE 1024
TestFuncResult test_cpath_join_path(void) { TestFuncResult test_cpath_join_path(void) {
b8 result; b8 result;
Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE); Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE);
Str8 out = wapp_str8_buf(MAIN_BUF_SIZE); Str8 out = wapp_str8_buf(MAIN_BUF_SIZE);
Str8 tmp = wapp_str8_buf(TMP_BUF_SIZE); Str8 tmp = wapp_str8_buf(TMP_BUF_SIZE);
wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP, WAPP_PATH_SEP); wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP, WAPP_PATH_SEP);
wapp_str8_format(&tmp, "%c", WAPP_PATH_SEP); wapp_str8_format(&tmp, "%c", WAPP_PATH_SEP);
Str8List parts = wapp_dbl_list(Str8, Str8List); Str8List parts = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_node_from_str8(tmp)); wapp_dbl_list_push_back(Str8, &parts, &tmp);
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_node_from_cstr("home")); wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_lit("home"));
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_node_from_cstr("abdelrahman")); wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_lit("abdelrahman"));
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_node_from_cstr("Documents")); wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_lit("Documents"));
wapp_cpath_join_path(&out, &parts); wapp_cpath_join_path(&out, &parts);
result = wapp_str8_equal(&out, &expected); result = wapp_str8_equal(&out, &expected);
wapp_dbl_list_pop_front(Str8, Str8Node, &parts); wapp_dbl_list_pop_front(Str8, &parts);
wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP); wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP);
@@ -33,8 +33,8 @@ TestFuncResult test_cpath_join_path(void) {
result = result && wapp_str8_equal(&out, &expected); result = result && wapp_str8_equal(&out, &expected);
wapp_str8_concat_capped(&tmp, &wapp_str8_lit_ro("home")); wapp_str8_concat_capped(&tmp, &wapp_str8_lit_ro("home"));
wapp_dbl_list_pop_front(Str8, Str8Node, &parts); wapp_dbl_list_pop_front(Str8, &parts);
wapp_dbl_list_push_front(Str8, &parts, &wapp_str8_node_from_str8(tmp)); wapp_dbl_list_push_front(Str8, &parts, &tmp);
wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP, WAPP_PATH_SEP); wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP, WAPP_PATH_SEP);
@@ -42,8 +42,8 @@ TestFuncResult test_cpath_join_path(void) {
result = result && wapp_str8_equal(&out, &expected); result = result && wapp_str8_equal(&out, &expected);
wapp_str8_format(&tmp, "home%c", WAPP_PATH_SEP); wapp_str8_format(&tmp, "home%c", WAPP_PATH_SEP);
wapp_dbl_list_pop_front(Str8, Str8Node, &parts); wapp_dbl_list_pop_front(Str8, &parts);
wapp_dbl_list_push_front(Str8, &parts, &wapp_str8_node_from_cstr("home")); wapp_dbl_list_push_front(Str8, &parts, &wapp_str8_lit("home"));
wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP); wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP);
@@ -53,24 +53,24 @@ TestFuncResult test_cpath_join_path(void) {
wapp_dbl_list_empty(Str8, &parts); wapp_dbl_list_empty(Str8, &parts);
wapp_str8_format(&tmp, "%chome", WAPP_PATH_SEP); wapp_str8_format(&tmp, "%chome", WAPP_PATH_SEP);
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_node_from_str8(tmp)); wapp_dbl_list_push_back(Str8, &parts, &tmp);
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_node_from_cstr("")); wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_lit(""));
wapp_str8_format(&expected, "%chome", WAPP_PATH_SEP); wapp_str8_format(&expected, "%chome", WAPP_PATH_SEP);
wapp_cpath_join_path(&out, &parts); wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected); result = result && wapp_str8_equal(&out, &expected);
wapp_dbl_list_pop_front(Str8, Str8Node, &parts); wapp_dbl_list_pop_front(Str8, &parts);
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_node_from_cstr("")); wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_lit(""));
wapp_str8_format(&expected, "%s", ""); wapp_str8_format(&expected, "%s", "");
wapp_cpath_join_path(&out, &parts); wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected); result = result && wapp_str8_equal(&out, &expected);
wapp_dbl_list_pop_back(Str8, Str8Node, &parts); wapp_dbl_list_pop_back(Str8, &parts);
wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_node_from_cstr("home")); wapp_dbl_list_push_back(Str8, &parts, &wapp_str8_lit("home"));
wapp_str8_copy_cstr_capped(&expected, "home"); wapp_str8_copy_cstr_capped(&expected, "home");
@@ -89,8 +89,8 @@ TestFuncResult test_cpath_dirname(void) {
b8 result; b8 result;
Str8 *output = NULL; Str8 *output = NULL;
Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE); Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE);
Str8 tmp = wapp_str8_buf(TMP_BUF_SIZE); Str8 tmp = wapp_str8_buf(TMP_BUF_SIZE);
// CASE 1 // CASE 1
wapp_str8_format(&tmp, "%c", WAPP_PATH_SEP); wapp_str8_format(&tmp, "%c", WAPP_PATH_SEP);
@@ -137,8 +137,8 @@ TestFuncResult test_cpath_dirup(void) {
b8 result; b8 result;
Str8 *output = NULL; Str8 *output = NULL;
Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE); Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE);
Str8 tmp = wapp_str8_buf(TMP_BUF_SIZE); Str8 tmp = wapp_str8_buf(TMP_BUF_SIZE);
// CASE 1 // CASE 1
wapp_str8_format(&tmp, "%c", WAPP_PATH_SEP); wapp_str8_format(&tmp, "%c", WAPP_PATH_SEP);

View File

@@ -3,37 +3,36 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#define MAIN_BUF_SIZE 4096 #define MAIN_BUF_SIZE 4096
#define TMP_BUF_SIZE 1024 #define TMP_BUF_SIZE 1024
TestFuncResult test_cpath_join_path(void) { TestFuncResult test_cpath_join_path(void) {
b8 result; b8 result;
Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE); Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE);
Str8 out = wapp_str8_buf(MAIN_BUF_SIZE); Str8 out = wapp_str8_buf(MAIN_BUF_SIZE);
Str8 tmp = wapp_str8_buf(TMP_BUF_SIZE); Str8 tmp = wapp_str8_buf(TMP_BUF_SIZE);
wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP, WAPP_PATH_SEP); wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP, WAPP_PATH_SEP);
wapp_str8_format(&tmp, "%c", WAPP_PATH_SEP); wapp_str8_format(&tmp, "%c", WAPP_PATH_SEP);
Str8List parts = wapp_dbl_list(Str8, Str8List); Str8List parts = wapp_dbl_list(Str8);
Str8Node tmp_node = wapp_str8_node_from_str8(tmp); wapp_dbl_list_push_back(Str8, &parts, &tmp);
wapp_dbl_list_push_back(Str8, &parts, &tmp_node);
Str8Node home_node = wapp_str8_node_from_cstr("home"); Str8 home = wapp_str8_lit("home");
wapp_dbl_list_push_back(Str8, &parts, &home_node); wapp_dbl_list_push_back(Str8, &parts, &home);
Str8Node user_node = wapp_str8_node_from_cstr("abdelrahman"); Str8 user = wapp_str8_lit("abdelrahman");
wapp_dbl_list_push_back(Str8, &parts, &user_node); wapp_dbl_list_push_back(Str8, &parts, &user);
Str8Node docs_node = wapp_str8_node_from_cstr("Documents"); Str8 docs = wapp_str8_lit("Documents");
wapp_dbl_list_push_back(Str8, &parts, &docs_node); wapp_dbl_list_push_back(Str8, &parts, &docs);
wapp_cpath_join_path(&out, &parts); wapp_cpath_join_path(&out, &parts);
result = wapp_str8_equal(&out, &expected); result = wapp_str8_equal(&out, &expected);
wapp_dbl_list_pop_front(Str8, Str8Node, &parts); wapp_dbl_list_pop_front(Str8, &parts);
wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP); wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP);
@@ -42,10 +41,9 @@ TestFuncResult test_cpath_join_path(void) {
Str8RO str = wapp_str8_lit_ro("home"); Str8RO str = wapp_str8_lit_ro("home");
wapp_str8_concat_capped(&tmp, &str); wapp_str8_concat_capped(&tmp, &str);
wapp_dbl_list_pop_front(Str8, Str8Node, &parts); wapp_dbl_list_pop_front(Str8, &parts);
Str8Node tmp_node_2 = wapp_str8_node_from_str8(tmp); wapp_dbl_list_push_front(Str8, &parts, &tmp);
wapp_dbl_list_push_front(Str8, &parts, &tmp_node_2);
wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP, WAPP_PATH_SEP); wapp_str8_format(&expected, "%chome%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP, WAPP_PATH_SEP);
@@ -53,10 +51,10 @@ TestFuncResult test_cpath_join_path(void) {
result = result && wapp_str8_equal(&out, &expected); result = result && wapp_str8_equal(&out, &expected);
wapp_str8_format(&tmp, "home%c", WAPP_PATH_SEP); wapp_str8_format(&tmp, "home%c", WAPP_PATH_SEP);
wapp_dbl_list_pop_front(Str8, Str8Node, &parts); wapp_dbl_list_pop_front(Str8, &parts);
Str8Node home_node_2 = wapp_str8_node_from_cstr("home"); Str8 home_2 = wapp_str8_lit("home");
wapp_dbl_list_push_front(Str8, &parts, &home_node_2); wapp_dbl_list_push_front(Str8, &parts, &home_2);
wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP); wapp_str8_format(&expected, "home%cabdelrahman%cDocuments", WAPP_PATH_SEP, WAPP_PATH_SEP);
@@ -67,31 +65,30 @@ TestFuncResult test_cpath_join_path(void) {
wapp_str8_format(&tmp, "%chome", WAPP_PATH_SEP); wapp_str8_format(&tmp, "%chome", WAPP_PATH_SEP);
Str8Node tmp_node_3 = wapp_str8_node_from_str8(tmp); wapp_dbl_list_push_back(Str8, &parts, &tmp);
wapp_dbl_list_push_back(Str8, &parts, &tmp_node_3);
Str8Node empty_node = wapp_str8_node_from_cstr(""); Str8 empty = wapp_str8_lit("");
wapp_dbl_list_push_back(Str8, &parts, &empty_node); wapp_dbl_list_push_back(Str8, &parts, &empty);
wapp_str8_format(&expected, "%chome", WAPP_PATH_SEP); wapp_str8_format(&expected, "%chome", WAPP_PATH_SEP);
wapp_cpath_join_path(&out, &parts); wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected); result = result && wapp_str8_equal(&out, &expected);
wapp_dbl_list_pop_front(Str8, Str8Node, &parts); wapp_dbl_list_pop_front(Str8, &parts);
Str8Node empty_node_2 = wapp_str8_node_from_cstr(""); Str8 empty_2 = wapp_str8_lit("");
wapp_dbl_list_push_back(Str8, &parts, &empty_node_2); wapp_dbl_list_push_back(Str8, &parts, &empty_2);
wapp_str8_format(&expected, "%s", ""); wapp_str8_format(&expected, "%s", "");
wapp_cpath_join_path(&out, &parts); wapp_cpath_join_path(&out, &parts);
result = result && wapp_str8_equal(&out, &expected); result = result && wapp_str8_equal(&out, &expected);
wapp_dbl_list_pop_back(Str8, Str8Node, &parts); wapp_dbl_list_pop_back(Str8, &parts);
Str8Node home_node_3 = wapp_str8_node_from_cstr("home"); Str8 home_3 = wapp_str8_lit("home");
wapp_dbl_list_push_back(Str8, &parts, &home_node_3); wapp_dbl_list_push_back(Str8, &parts, &home_3);
wapp_str8_copy_cstr_capped(&expected, "home"); wapp_str8_copy_cstr_capped(&expected, "home");
@@ -110,8 +107,8 @@ TestFuncResult test_cpath_dirname(void) {
b8 result; b8 result;
Str8 *output = nullptr; Str8 *output = nullptr;
Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE); Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE);
Str8 tmp = wapp_str8_buf(TMP_BUF_SIZE); Str8 tmp = wapp_str8_buf(TMP_BUF_SIZE);
// CASE 1 // CASE 1
wapp_str8_format(&tmp, "%c", WAPP_PATH_SEP); wapp_str8_format(&tmp, "%c", WAPP_PATH_SEP);
@@ -123,14 +120,14 @@ TestFuncResult test_cpath_dirname(void) {
// CASE 2 // CASE 2
wapp_str8_format(&expected, "%s", "."); wapp_str8_format(&expected, "%s", ".");
Str8 path = wapp_str8_lit("home"); Str8 path = wapp_str8_lit("home");
output = wapp_cpath_dirname(&arena, &path); output = wapp_cpath_dirname(&arena, &path);
result = result && output != nullptr && wapp_str8_equal(output, &expected); result = result && output != nullptr && wapp_str8_equal(output, &expected);
// CASE 3 // CASE 3
path = wapp_str8_lit(""); path = wapp_str8_lit("");
output = wapp_cpath_dirname(&arena, &path); output = wapp_cpath_dirname(&arena, &path);
result = result && output != nullptr && wapp_str8_equal(output, &expected); result = result && output != nullptr && wapp_str8_equal(output, &expected);
// CASE 4 // CASE 4
wapp_str8_format(&tmp, "%chome%ctest", WAPP_PATH_SEP, WAPP_PATH_SEP); wapp_str8_format(&tmp, "%chome%ctest", WAPP_PATH_SEP, WAPP_PATH_SEP);
@@ -160,8 +157,8 @@ TestFuncResult test_cpath_dirup(void) {
b8 result; b8 result;
Str8 *output = nullptr; Str8 *output = nullptr;
Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE); Str8 expected = wapp_str8_buf(MAIN_BUF_SIZE);
Str8 tmp = wapp_str8_buf(TMP_BUF_SIZE); Str8 tmp = wapp_str8_buf(TMP_BUF_SIZE);
// CASE 1 // CASE 1
wapp_str8_format(&tmp, "%c", WAPP_PATH_SEP); wapp_str8_format(&tmp, "%c", WAPP_PATH_SEP);

118
tests/file/test_file.c Normal file
View File

@@ -0,0 +1,118 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "test_file.h"
#define DST_CAPACITY 5
wapp_intern Allocator arena = {0};
wapp_intern Str8RO test_filename = wapp_str8_lit_ro_initialiser_list("wapptest.bin");
wapp_intern Str8RO new_filename = wapp_str8_lit_ro_initialiser_list("wapptest2.bin");
wapp_intern WFile *test_fp = NULL;
wapp_intern I32Array src_array1 = wapp_array(i32, 0, 1, 2, 3, 4);
wapp_intern I32Array src_array2 = wapp_array(i32, 5, 6, 7, 8, 9);
wapp_intern I32Array src_array3 = wapp_array(i32, 10, 11, 12, 13, 14);
wapp_intern I32Array dst_array = wapp_array_with_capacity(i32, DST_CAPACITY, false);
wapp_intern i32 dst_buf[DST_CAPACITY] = {0};
TestFuncResult test_wapp_file_open(void) {
arena = wapp_mem_arena_allocator_init(KiB(16));
test_fp = wapp_file_open(&arena, &test_filename, WAPP_ACCESS_WRITE_EX);
return wapp_tester_result(test_fp != NULL);
}
TestFuncResult test_wapp_file_get_current_position(void) {
i64 pos = wapp_file_get_current_position(test_fp);
return wapp_tester_result(pos == 0);
}
TestFuncResult test_wapp_file_seek(void) {
wapp_file_write_array((GenericArray)src_array1, test_fp, wapp_array_count(src_array1));
i64 seek_result = wapp_file_seek(test_fp, 0, WAPP_SEEK_END);
b8 result = seek_result == (i64)(wapp_array_count(src_array1) * wapp_array_item_size(src_array1));
wapp_file_seek(test_fp, 0, WAPP_SEEK_START);
return wapp_tester_result(result);
}
TestFuncResult test_wapp_file_get_length(void) {
i64 length = wapp_file_get_length(test_fp);
return wapp_tester_result(length == (i64)(wapp_array_count(src_array1) * wapp_array_item_size(src_array1)));
}
TestFuncResult test_wapp_file_read(void) {
wapp_file_seek(test_fp, 0, WAPP_SEEK_START);
u64 byte_count = DST_CAPACITY * sizeof(i32);
u64 count = wapp_file_read((void *)dst_buf, test_fp, byte_count);
b8 result = count == byte_count;
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
u64 index = 0;
b8 running = true;
while (running) {
result = result && (dst_buf[index] == *wapp_array_get(i32, src_array1, index));
++index;
running = index < DST_CAPACITY;
}
return wapp_tester_result(result);
}
TestFuncResult test_wapp_file_write(void) {
wapp_file_seek(test_fp, 0, WAPP_SEEK_END);
u64 expected_count = wapp_array_count(src_array2) * wapp_array_item_size(src_array2);
i64 count = wapp_file_write((void *)src_array2, test_fp, expected_count);
return wapp_tester_result(count >= 0 && (u64)count == expected_count);
}
TestFuncResult test_wapp_file_read_array(void) {
wapp_file_seek(test_fp, 0, WAPP_SEEK_START);
u64 count = wapp_file_read_array((GenericArray)dst_array, test_fp, wapp_array_count(src_array1));
b8 result = count == wapp_array_count(src_array1) &&
wapp_array_count(dst_array) == wapp_array_count(src_array1);
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
u64 index = 0;
b8 running = true;
while (running) {
result = result && (*wapp_array_get(i32, dst_array, index) == *wapp_array_get(i32, src_array1, index));
++index;
running = index < wapp_array_count(dst_array);
}
return wapp_tester_result(result);
}
TestFuncResult test_wapp_file_write_array(void) {
wapp_file_seek(test_fp, 0, WAPP_SEEK_END);
i64 count = wapp_file_write_array((GenericArray)src_array3, test_fp, wapp_array_count(src_array3));
return wapp_tester_result(count >= 0 && (u64)count == wapp_array_count(src_array3));
}
TestFuncResult test_wapp_file_flush(void) {
i32 flush_result = wapp_file_flush(test_fp);
return wapp_tester_result(flush_result == 0);
}
TestFuncResult test_wapp_file_close(void) {
i32 close_result = wapp_file_close(test_fp);
return wapp_tester_result(close_result == 0);
}
TestFuncResult test_wapp_file_rename(void) {
i32 rename_result = wapp_file_rename(&test_filename, &new_filename);
return wapp_tester_result(rename_result == 0);
}
TestFuncResult test_wapp_file_remove(void) {
i32 remove_result = wapp_file_remove(&new_filename);
return wapp_tester_result(remove_result == 0);
}

122
tests/file/test_file.cc Normal file
View File

@@ -0,0 +1,122 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "test_file.h"
#define DST_CAPACITY 5
wapp_intern Allocator arena = {};
wapp_intern Str8RO test_filename = wapp_str8_lit_ro_initialiser_list("wapptest.bin");
wapp_intern Str8RO new_filename = wapp_str8_lit_ro_initialiser_list("wapptest2.bin");
wapp_intern WFile *test_fp = NULL;
wapp_intern i32 dst_buf[DST_CAPACITY] = {0};
wapp_intern I32Array src_array1;
wapp_intern I32Array src_array2;
wapp_intern I32Array src_array3;
wapp_intern I32Array dst_array ;
TestFuncResult test_wapp_file_open(void) {
arena = wapp_mem_arena_allocator_init(KiB(16));
src_array1 = wapp_array(i32, 0, 1, 2, 3, 4);
src_array2 = wapp_array(i32, 5, 6, 7, 8, 9);
src_array3 = wapp_array(i32, 10, 11, 12, 13, 14);
dst_array = wapp_array_with_capacity(i32, DST_CAPACITY, false);
test_fp = wapp_file_open(&arena, &test_filename, WAPP_ACCESS_WRITE_EX);
return wapp_tester_result(test_fp != NULL);
}
TestFuncResult test_wapp_file_get_current_position(void) {
i64 pos = wapp_file_get_current_position(test_fp);
return wapp_tester_result(pos == 0);
}
TestFuncResult test_wapp_file_seek(void) {
wapp_file_write_array((GenericArray)src_array1, test_fp, wapp_array_count(src_array1));
i64 seek_result = wapp_file_seek(test_fp, 0, WAPP_SEEK_END);
b8 result = seek_result == (i64)(wapp_array_count(src_array1) * wapp_array_item_size(src_array1));
wapp_file_seek(test_fp, 0, WAPP_SEEK_START);
return wapp_tester_result(result);
}
TestFuncResult test_wapp_file_get_length(void) {
i64 length = wapp_file_get_length(test_fp);
return wapp_tester_result(length == (i64)(wapp_array_count(src_array1) * wapp_array_item_size(src_array1)));
}
TestFuncResult test_wapp_file_read(void) {
wapp_file_seek(test_fp, 0, WAPP_SEEK_START);
u64 byte_count = DST_CAPACITY * sizeof(i32);
u64 count = wapp_file_read((void *)dst_buf, test_fp, byte_count);
b8 result = count == byte_count;
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
u64 index = 0;
b8 running = true;
while (running) {
result = result && (dst_buf[index] == *wapp_array_get(i32, src_array1, index));
++index;
running = index < DST_CAPACITY;
}
return wapp_tester_result(result);
}
TestFuncResult test_wapp_file_write(void) {
wapp_file_seek(test_fp, 0, WAPP_SEEK_END);
u64 expected_count = wapp_array_count(src_array2) * wapp_array_item_size(src_array2);
i64 count = wapp_file_write((void *)src_array2, test_fp, expected_count);
return wapp_tester_result(count >= 0 && (u64)count == expected_count);
}
TestFuncResult test_wapp_file_read_array(void) {
wapp_file_seek(test_fp, 0, WAPP_SEEK_START);
u64 count = wapp_file_read_array((GenericArray)dst_array, test_fp, wapp_array_count(src_array1));
b8 result = count == wapp_array_count(src_array1) &&
wapp_array_count(dst_array) == wapp_array_count(src_array1);
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings
u64 index = 0;
b8 running = true;
while (running) {
result = result && (*wapp_array_get(i32, dst_array, index) == *wapp_array_get(i32, src_array1, index));
++index;
running = index < wapp_array_count(dst_array);
}
return wapp_tester_result(result);
}
TestFuncResult test_wapp_file_write_array(void) {
wapp_file_seek(test_fp, 0, WAPP_SEEK_END);
i64 count = wapp_file_write_array((GenericArray)src_array3, test_fp, wapp_array_count(src_array3));
return wapp_tester_result(count >= 0 && (u64)count == wapp_array_count(src_array3));
}
TestFuncResult test_wapp_file_flush(void) {
i32 flush_result = wapp_file_flush(test_fp);
return wapp_tester_result(flush_result == 0);
}
TestFuncResult test_wapp_file_close(void) {
i32 close_result = wapp_file_close(test_fp);
return wapp_tester_result(close_result == 0);
}
TestFuncResult test_wapp_file_rename(void) {
i32 rename_result = wapp_file_rename(&test_filename, &new_filename);
return wapp_tester_result(rename_result == 0);
}
TestFuncResult test_wapp_file_remove(void) {
i32 remove_result = wapp_file_remove(&new_filename);
return wapp_tester_result(remove_result == 0);
}

21
tests/file/test_file.h Normal file
View File

@@ -0,0 +1,21 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef TEST_FILE_H
#define TEST_FILE_H
#include "wapp.h"
TestFuncResult test_wapp_file_open(void);
TestFuncResult test_wapp_file_get_current_position(void);
TestFuncResult test_wapp_file_seek(void);
TestFuncResult test_wapp_file_get_length(void);
TestFuncResult test_wapp_file_read(void);
TestFuncResult test_wapp_file_write(void);
TestFuncResult test_wapp_file_read_array(void);
TestFuncResult test_wapp_file_write_array(void);
TestFuncResult test_wapp_file_flush(void);
TestFuncResult test_wapp_file_close(void);
TestFuncResult test_wapp_file_rename(void);
TestFuncResult test_wapp_file_remove(void);
#endif // !TEST_FILE_H

98
tests/queue/test_queue.c Normal file
View File

@@ -0,0 +1,98 @@
// vim:fileencoding=utf-8:foldmethod=marker
#include "wapp.h"
#include "test_queue.h"
#define CAPACITY 8
TestFuncResult test_queue_push(void) {
I32Queue queue = wapp_queue(i32, CAPACITY);
for (u64 i = 0; i < CAPACITY; ++i) {
i32 item = (i32)i;
wapp_queue_push(i32, &queue, &item);
}
b8 result = true;
for (u64 i = 0; i < CAPACITY; ++i) {
i32 *value = ((i32 *)(queue.items)) + i;
result = result && value != NULL && *value == (i32)i;
}
return wapp_tester_result(result);
}
TestFuncResult test_queue_push_alloc(void) {
Allocator arena = wapp_mem_arena_allocator_init(MiB(64));
I32Queue queue = wapp_queue(i32, CAPACITY);
for (u64 i = 0; i < CAPACITY; ++i) {
i32 item = (i32)i;
wapp_queue_push(i32, &queue, &item);
}
b8 result = true;
i32 item = 8;
u64 new_capacity = CAPACITY * 2;
I32Queue *new_queue = wapp_queue_push_alloc(i32, &arena, &queue, &item);
if (new_queue && new_queue != &queue) {
queue = *new_queue;
}
u64 capacity = wapp_queue_capacity(&queue);
result = result && capacity == new_capacity;
for (u64 i = 0; i < 2; ++i) {
wapp_queue_pop(i32, &queue);
}
u64 remaining = wapp_queue_capacity(&queue) - queue.count;
for (u64 i = 0; i < remaining; ++i) {
item = remaining + i;
wapp_queue_push(i32, &queue, &item);
}
++item;
new_queue = wapp_queue_push_alloc(i32, &arena, &queue, &item);
if (new_queue && new_queue != &queue) {
queue = *new_queue;
}
result = result && wapp_queue_capacity(&queue) == new_capacity * 2;
i32 *arr = (i32 *)queue.items;
for (u64 i = 0; i < queue.count; ++i) {
// NOTE (Abdelrahman): First queue value is currently 2
result = result && arr[i] == (i32)(2 + i);
}
wapp_mem_arena_allocator_destroy(&arena);
return wapp_tester_result(result);
}
TestFuncResult test_queue_pop(void) {
I32Queue queue = wapp_queue(i32, CAPACITY);
for (u64 i = 0; i < CAPACITY; ++i) {
i32 item = (i32)i;
wapp_queue_push(i32, &queue, &item);
}
b8 result = true;
u64 half_count = queue.count / 2;
for (u64 i = 0; i < half_count; ++i) {
i32 *value = wapp_queue_pop(i32, &queue);
result = result && value != NULL && *value == (i32)i;
}
for (u64 i = 0; i < half_count; ++i) {
i32 item = (i32)i + CAPACITY;
wapp_queue_push(i32, &queue, &item);
}
for (u64 i = 0; i < CAPACITY; ++i) {
i32 *value = wapp_queue_pop(i32, &queue);
result = result && value != NULL && *value == (i32)half_count + (i32)i;
}
return wapp_tester_result(result);
}

96
tests/queue/test_queue.cc Normal file
View File

@@ -0,0 +1,96 @@
#include "wapp.h"
#include "test_queue.h"
#define CAPACITY 8
TestFuncResult test_queue_push(void) {
I32Queue queue = wapp_queue(i32, CAPACITY);
for (u64 i = 0; i < CAPACITY; ++i) {
i32 item = (i32)i;
wapp_queue_push(i32, &queue, &item);
}
b8 result = true;
for (u64 i = 0; i < CAPACITY; ++i) {
i32 *value = ((i32 *)(queue.items)) + i;
result = result && value != NULL && *value == (i32)i;
}
return wapp_tester_result(result);
}
TestFuncResult test_queue_push_alloc(void) {
Allocator arena = wapp_mem_arena_allocator_init(MiB(64));
I32Queue queue = wapp_queue(i32, CAPACITY);
for (u64 i = 0; i < CAPACITY; ++i) {
i32 item = (i32)i;
wapp_queue_push(i32, &queue, &item);
}
b8 result = true;
i32 item = 8;
u64 new_capacity = CAPACITY * 2;
I32Queue *new_queue = wapp_queue_push_alloc(i32, &arena, &queue, &item);
if (new_queue && new_queue != &queue) {
queue = *new_queue;
}
u64 capacity = wapp_queue_capacity(&queue);
result = result && capacity == new_capacity;
for (u64 i = 0; i < 2; ++i) {
wapp_queue_pop(i32, &queue);
}
u64 remaining = wapp_queue_capacity(&queue) - queue.count;
for (u64 i = 0; i < remaining; ++i) {
item = remaining + i;
wapp_queue_push(i32, &queue, &item);
}
++item;
new_queue = wapp_queue_push_alloc(i32, &arena, &queue, &item);
if (new_queue && new_queue != &queue) {
queue = *new_queue;
}
result = result && wapp_queue_capacity(&queue) == new_capacity * 2;
i32 *arr = (i32 *)queue.items;
for (u64 i = 0; i < queue.count; ++i) {
// NOTE (Abdelrahman): First queue value is currently 2
result = result && arr[i] == (i32)(2 + i);
}
wapp_mem_arena_allocator_destroy(&arena);
return wapp_tester_result(result);
}
TestFuncResult test_queue_pop(void) {
I32Queue queue = wapp_queue(i32, CAPACITY);
for (u64 i = 0; i < CAPACITY; ++i) {
i32 item = (i32)i;
wapp_queue_push(i32, &queue, &item);
}
b8 result = true;
u64 half_count = queue.count / 2;
for (u64 i = 0; i < half_count; ++i) {
i32 *value = wapp_queue_pop(i32, &queue);
result = result && value != NULL && *value == (i32)i;
}
for (u64 i = 0; i < half_count; ++i) {
i32 item = (i32)i + CAPACITY;
wapp_queue_push(i32, &queue, &item);
}
for (u64 i = 0; i < CAPACITY; ++i) {
i32 *value = wapp_queue_pop(i32, &queue);
result = result && value != NULL && *value == (i32)half_count + (i32)i;
}
return wapp_tester_result(result);
}

12
tests/queue/test_queue.h Normal file
View File

@@ -0,0 +1,12 @@
// vim:fileencoding=utf-8:foldmethod=marker
#ifndef TEST_QUEUE_H
#define TEST_QUEUE_H
#include "wapp.h"
TestFuncResult test_queue_push(void);
TestFuncResult test_queue_push_alloc(void);
TestFuncResult test_queue_pop(void);
#endif // !TEST_QUEUE_H

View File

@@ -5,58 +5,58 @@
#include <string.h> #include <string.h>
TestFuncResult test_commander_cmd_success(void) { TestFuncResult test_commander_cmd_success(void) {
Str8List cmd = wapp_dbl_list(Str8, Str8List); Str8List cmd = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_node_from_cstr("echo")); wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit("echo"));
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_node_from_cstr("hello world")); wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit("hello world"));
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, &cmd); CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, &cmd);
b8 succeeded = result.exited && result.exit_code == EXIT_SUCCESS && b8 succeeded = result.exited && result.exit_code == EXIT_SUCCESS &&
result.error == SHELL_ERR_NO_ERROR; result.error == SHELL_ERR_NO_ERROR;
return wapp_tester_result(succeeded); return wapp_tester_result(succeeded);
} }
TestFuncResult test_commander_cmd_failure(void) { TestFuncResult test_commander_cmd_failure(void) {
Str8List cmd = wapp_dbl_list(Str8, Str8List); Str8List cmd = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_node_from_cstr("grep")); wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit("grep"));
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, &cmd); CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, NULL, &cmd);
b8 failed = result.exited && result.exit_code != EXIT_SUCCESS && b8 failed = result.exited && result.exit_code != EXIT_SUCCESS &&
result.error == SHELL_ERR_NO_ERROR; result.error == SHELL_ERR_NO_ERROR;
return wapp_tester_result(failed); return wapp_tester_result(failed);
} }
TestFuncResult test_commander_cmd_out_buf_success(void) { TestFuncResult test_commander_cmd_out_buf_success(void) {
Str8 buf = wapp_str8_buf(64); Str8 buf = wapp_str8_buf(64);
Str8 expected = wapp_str8_buf(64); Str8 expected = wapp_str8_buf(64);
char msg[] = "hello world"; char msg[] = "hello world";
wapp_str8_copy_cstr_capped(&expected, msg); wapp_str8_copy_cstr_capped(&expected, msg);
Str8List cmd = wapp_dbl_list(Str8, Str8List); Str8List cmd = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_node_from_cstr("echo")); wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit("echo"));
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_node_from_cstr(msg)); wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit(msg));
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd); CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd);
b8 succeeded = result.exited && result.exit_code == EXIT_SUCCESS && b8 succeeded = result.exited && result.exit_code == EXIT_SUCCESS &&
result.error == SHELL_ERR_NO_ERROR && wapp_str8_equal_to_count(&buf, &expected, strlen(msg)); result.error == SHELL_ERR_NO_ERROR && wapp_str8_equal_to_count(&buf, &expected, strlen(msg));
return wapp_tester_result(succeeded); return wapp_tester_result(succeeded);
} }
TestFuncResult test_commander_cmd_out_buf_failure(void) { TestFuncResult test_commander_cmd_out_buf_failure(void) {
Str8 buf = wapp_str8_buf(4); Str8 buf = wapp_str8_buf(4);
Str8 expected = wapp_str8_buf(64); Str8 expected = wapp_str8_buf(64);
char msg[] = "hello world"; char msg[] = "hello world";
wapp_str8_copy_cstr_capped(&expected, msg); wapp_str8_copy_cstr_capped(&expected, msg);
Str8List cmd = wapp_dbl_list(Str8, Str8List); Str8List cmd = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_node_from_cstr("echo")); wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit("echo"));
wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_node_from_cstr(msg)); wapp_dbl_list_push_back(Str8, &cmd, &wapp_str8_lit(msg));
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd); CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd);
b8 failed = !result.exited && result.exit_code != EXIT_SUCCESS && b8 failed = !result.exited && result.exit_code != EXIT_SUCCESS &&
result.error == SHELL_ERR_OUT_BUF_FULL && !wapp_str8_equal(&buf, &expected); result.error == SHELL_ERR_OUT_BUF_FULL && !wapp_str8_equal(&buf, &expected);
return wapp_tester_result(failed); return wapp_tester_result(failed);
} }

View File

@@ -5,65 +5,65 @@
#include <string.h> #include <string.h>
TestFuncResult test_commander_cmd_success(void) { TestFuncResult test_commander_cmd_success(void) {
Str8List cmd = wapp_dbl_list(Str8, Str8List); Str8List cmd = wapp_dbl_list(Str8);
Str8Node echo = wapp_str8_node_from_cstr("echo"); Str8 echo = wapp_str8_lit("echo");
Str8Node msg = wapp_str8_node_from_cstr("hello world"); Str8 msg = wapp_str8_lit("hello world");
wapp_dbl_list_push_back(Str8, &cmd, &echo); wapp_dbl_list_push_back(Str8, &cmd, &echo);
wapp_dbl_list_push_back(Str8, &cmd, &msg); wapp_dbl_list_push_back(Str8, &cmd, &msg);
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, nullptr, &cmd); CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, nullptr, &cmd);
b8 succeeded = result.exited && result.exit_code == EXIT_SUCCESS && b8 succeeded = result.exited && result.exit_code == EXIT_SUCCESS &&
result.error == SHELL_ERR_NO_ERROR; result.error == SHELL_ERR_NO_ERROR;
return wapp_tester_result(succeeded); return wapp_tester_result(succeeded);
} }
TestFuncResult test_commander_cmd_failure(void) { TestFuncResult test_commander_cmd_failure(void) {
Str8List cmd = wapp_dbl_list(Str8, Str8List); Str8List cmd = wapp_dbl_list(Str8);
Str8Node grep = wapp_str8_node_from_cstr("grep"); Str8 grep = wapp_str8_lit("grep");
wapp_dbl_list_push_back(Str8, &cmd, &grep); wapp_dbl_list_push_back(Str8, &cmd, &grep);
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, nullptr, &cmd); CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_DISCARD, nullptr, &cmd);
b8 failed = result.exited && result.exit_code != EXIT_SUCCESS && b8 failed = result.exited && result.exit_code != EXIT_SUCCESS &&
result.error == SHELL_ERR_NO_ERROR; result.error == SHELL_ERR_NO_ERROR;
return wapp_tester_result(failed); return wapp_tester_result(failed);
} }
TestFuncResult test_commander_cmd_out_buf_success(void) { TestFuncResult test_commander_cmd_out_buf_success(void) {
Str8 buf = wapp_str8_buf(64); Str8 buf = wapp_str8_buf(64);
Str8 expected = wapp_str8_buf(64); Str8 expected = wapp_str8_buf(64);
char msg[] = "hello world"; char msg[] = "hello world";
wapp_str8_copy_cstr_capped(&expected, msg); wapp_str8_copy_cstr_capped(&expected, msg);
Str8List cmd = wapp_dbl_list(Str8, Str8List); Str8List cmd = wapp_dbl_list(Str8);
Str8Node echo = wapp_str8_node_from_cstr("echo"); Str8 echo = wapp_str8_lit("echo");
Str8Node arg = wapp_str8_node_from_cstr(msg); Str8 arg = wapp_str8_lit(msg);
wapp_dbl_list_push_back(Str8, &cmd, &echo); wapp_dbl_list_push_back(Str8, &cmd, &echo);
wapp_dbl_list_push_back(Str8, &cmd, &arg); wapp_dbl_list_push_back(Str8, &cmd, &arg);
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd); CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd);
b8 succeeded = result.exited && result.exit_code == EXIT_SUCCESS && b8 succeeded = result.exited && result.exit_code == EXIT_SUCCESS &&
result.error == SHELL_ERR_NO_ERROR && wapp_str8_equal_to_count(&buf, &expected, strlen(msg)); result.error == SHELL_ERR_NO_ERROR && wapp_str8_equal_to_count(&buf, &expected, strlen(msg));
return wapp_tester_result(succeeded); return wapp_tester_result(succeeded);
} }
TestFuncResult test_commander_cmd_out_buf_failure(void) { TestFuncResult test_commander_cmd_out_buf_failure(void) {
Str8 buf = wapp_str8_buf(4); Str8 buf = wapp_str8_buf(4);
Str8 expected = wapp_str8_buf(64); Str8 expected = wapp_str8_buf(64);
char msg[] = "hello world"; char msg[] = "hello world";
wapp_str8_copy_cstr_capped(&expected, msg); wapp_str8_copy_cstr_capped(&expected, msg);
Str8List cmd = wapp_dbl_list(Str8, Str8List); Str8List cmd = wapp_dbl_list(Str8);
Str8Node echo = wapp_str8_node_from_cstr("echo"); Str8 echo = wapp_str8_lit("echo");
Str8Node arg = wapp_str8_node_from_cstr(msg); Str8 arg = wapp_str8_lit(msg);
wapp_dbl_list_push_back(Str8, &cmd, &echo); wapp_dbl_list_push_back(Str8, &cmd, &echo);
wapp_dbl_list_push_back(Str8, &cmd, &arg); wapp_dbl_list_push_back(Str8, &cmd, &arg);
CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd); CMDResult result = wapp_shell_commander_execute(SHELL_OUTPUT_CAPTURE, &buf, &cmd);
b8 failed = !result.exited && result.exit_code != EXIT_SUCCESS && b8 failed = !result.exited && result.exit_code != EXIT_SUCCESS &&
result.error == SHELL_ERR_OUT_BUF_FULL && !wapp_str8_equal(&buf, &expected); result.error == SHELL_ERR_OUT_BUF_FULL && !wapp_str8_equal(&buf, &expected);
return wapp_tester_result(failed); return wapp_tester_result(failed);
} }

View File

@@ -6,26 +6,26 @@
TestFuncResult test_str8_lit(void) { TestFuncResult test_str8_lit(void) {
b8 result; b8 result;
Str8 s1 = wapp_str8_lit("Hello world"); Str8 s1 = wapp_str8_lit("Hello world");
result = s1.capacity == 22 && s1.capacity != s1.size; result = s1.capacity == 22 && s1.capacity != s1.size;
Str8 s2 = wapp_str8_lit("Different strokes for different folks"); Str8 s2 = wapp_str8_lit("Different strokes for different folks");
result = result && s2.capacity == 74 && s2.capacity != s2.size; result = result && s2.capacity == 74 && s2.capacity != s2.size;
Str8 s3 = wapp_str8_lit("Discretion is the better part of valour"); Str8 s3 = wapp_str8_lit("Discretion is the better part of valour");
result = result && s3.capacity == 78 && s3.capacity != s3.size; result = result && s3.capacity == 78 && s3.capacity != s3.size;
Str8 s4 = wapp_str8_lit("Distance lends enchantment to the view"); Str8 s4 = wapp_str8_lit("Distance lends enchantment to the view");
result = result && s4.capacity == 76 && s4.capacity != s4.size; result = result && s4.capacity == 76 && s4.capacity != s4.size;
Str8 s5 = wapp_str8_lit("Do as I say, not as I do"); Str8 s5 = wapp_str8_lit("Do as I say, not as I do");
result = result && s5.capacity == 48 && s5.capacity != s5.size; result = result && s5.capacity == 48 && s5.capacity != s5.size;
Str8 s6 = wapp_str8_lit("Do as you would be done by"); Str8 s6 = wapp_str8_lit("Do as you would be done by");
result = result && s6.capacity == 52 && s6.capacity != s6.size; result = result && s6.capacity == 52 && s6.capacity != s6.size;
Str8 s7 = wapp_str8_lit("Do unto others as you would have them do to you"); Str8 s7 = wapp_str8_lit("Do unto others as you would have them do to you");
result = result && s7.capacity == 94 && s7.capacity != s7.size; result = result && s7.capacity == 94 && s7.capacity != s7.size;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -33,26 +33,26 @@ TestFuncResult test_str8_lit(void) {
TestFuncResult test_str8_lit_ro(void) { TestFuncResult test_str8_lit_ro(void) {
b8 result; b8 result;
Str8RO s1 = wapp_str8_lit_ro("Hello world"); Str8RO s1 = wapp_str8_lit_ro("Hello world");
result = s1.capacity == 11 && s1.capacity == s1.size; result = s1.capacity == 11 && s1.capacity == s1.size;
Str8RO s2 = wapp_str8_lit_ro("Different strokes for different folks"); Str8RO s2 = wapp_str8_lit_ro("Different strokes for different folks");
result = result && s2.capacity == 37 && s2.capacity == s2.size; result = result && s2.capacity == 37 && s2.capacity == s2.size;
Str8RO s3 = wapp_str8_lit_ro("Discretion is the better part of valour"); Str8RO s3 = wapp_str8_lit_ro("Discretion is the better part of valour");
result = result && s3.capacity == 39 && s3.capacity == s3.size; result = result && s3.capacity == 39 && s3.capacity == s3.size;
Str8RO s4 = wapp_str8_lit_ro("Distance lends enchantment to the view"); Str8RO s4 = wapp_str8_lit_ro("Distance lends enchantment to the view");
result = result && s4.capacity == 38 && s4.capacity == s4.size; result = result && s4.capacity == 38 && s4.capacity == s4.size;
Str8RO s5 = wapp_str8_lit_ro("Do as I say, not as I do"); Str8RO s5 = wapp_str8_lit_ro("Do as I say, not as I do");
result = result && s5.capacity == 24 && s5.capacity == s5.size; result = result && s5.capacity == 24 && s5.capacity == s5.size;
Str8RO s6 = wapp_str8_lit_ro("Do as you would be done by"); Str8RO s6 = wapp_str8_lit_ro("Do as you would be done by");
result = result && s6.capacity == 26 && s6.capacity == s6.size; result = result && s6.capacity == 26 && s6.capacity == s6.size;
Str8RO s7 = wapp_str8_lit_ro("Do unto others as you would have them do to you"); Str8RO s7 = wapp_str8_lit_ro("Do unto others as you would have them do to you");
result = result && s7.capacity == 47 && s7.capacity == s7.size; result = result && s7.capacity == 47 && s7.capacity == s7.size;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -60,17 +60,17 @@ TestFuncResult test_str8_lit_ro(void) {
TestFuncResult test_str8_buf(void) { TestFuncResult test_str8_buf(void) {
b8 result; b8 result;
Str8 s1 = wapp_str8_buf(1024); Str8 s1 = wapp_str8_buf(1024);
result = s1.capacity == 1024 && s1.size == 0; result = s1.capacity == 1024 && s1.size == 0;
Str8 s2 = wapp_str8_buf(2048); Str8 s2 = wapp_str8_buf(2048);
result = result && s2.capacity == 2048 && s2.size == 0; result = result && s2.capacity == 2048 && s2.size == 0;
Str8 s3 = wapp_str8_buf(4096); Str8 s3 = wapp_str8_buf(4096);
result = result && s3.capacity == 4096 && s3.size == 0; result = result && s3.capacity == 4096 && s3.size == 0;
Str8 s4 = wapp_str8_buf(8192); Str8 s4 = wapp_str8_buf(8192);
result = result && s4.capacity == 8192 && s4.size == 0; result = result && s4.capacity == 8192 && s4.size == 0;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -110,9 +110,9 @@ TestFuncResult test_str8_alloc_cstr(void) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
char *str = "Abdelrahman"; char *str = "Abdelrahman";
u64 length = strlen(str); u64 length = strlen(str);
Str8 *s = wapp_str8_alloc_cstr(&allocator, str); Str8 *s = wapp_str8_alloc_cstr(&allocator, str);
if (!s) { if (!s) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
@@ -131,8 +131,8 @@ TestFuncResult test_str8_alloc_str8(void) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
Str8 str = wapp_str8_lit("Abdelrahman"); Str8 str = wapp_str8_lit("Abdelrahman");
Str8 *s = wapp_str8_alloc_str8(&allocator, &str); Str8 *s = wapp_str8_alloc_str8(&allocator, &str);
if (!s) { if (!s) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
@@ -151,8 +151,8 @@ TestFuncResult test_str8_alloc_substr(void) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
Str8 str = wapp_str8_lit("Abdelrahman"); Str8 str = wapp_str8_lit("Abdelrahman");
Str8 *s = wapp_str8_alloc_substr(&allocator, &str, 3, 8); Str8 *s = wapp_str8_alloc_substr(&allocator, &str, 3, 8);
if (!s) { if (!s) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
@@ -167,66 +167,66 @@ TestFuncResult test_str8_alloc_substr(void) {
TestFuncResult test_str8_get_index_within_bounds(void) { TestFuncResult test_str8_get_index_within_bounds(void) {
b8 result; b8 result;
Str8RO s1 = wapp_str8_lit_ro("Hello world"); Str8RO s1 = wapp_str8_lit_ro("Hello world");
result = wapp_str8_get(&s1, 4) == 'o'; result = wapp_str8_get(&s1, 4) == 'o';
Str8RO s2 = wapp_str8_lit_ro("Different strokes for different folks"); Str8RO s2 = wapp_str8_lit_ro("Different strokes for different folks");
result = result && wapp_str8_get(&s2, 0) == 'D'; result = result && wapp_str8_get(&s2, 0) == 'D';
Str8RO s3 = wapp_str8_lit_ro("Discretion is the better part of valour"); Str8RO s3 = wapp_str8_lit_ro("Discretion is the better part of valour");
result = result && wapp_str8_get(&s3, 13) == ' '; result = result && wapp_str8_get(&s3, 13) == ' ';
Str8RO s4 = wapp_str8_lit_ro("Distance lends enchantment to the view"); Str8RO s4 = wapp_str8_lit_ro("Distance lends enchantment to the view");
result = result && wapp_str8_get(&s4, 20) == 'n'; result = result && wapp_str8_get(&s4, 20) == 'n';
Str8RO s5 = wapp_str8_lit_ro("Do as I say, not as I do"); Str8RO s5 = wapp_str8_lit_ro("Do as I say, not as I do");
result = result && wapp_str8_get(&s5, 11) == ','; result = result && wapp_str8_get(&s5, 11) == ',';
Str8RO s6 = wapp_str8_lit_ro("Do as you would be done by"); Str8RO s6 = wapp_str8_lit_ro("Do as you would be done by");
result = result && wapp_str8_get(&s6, 25) == 'y'; result = result && wapp_str8_get(&s6, 25) == 'y';
Str8RO s7 = wapp_str8_lit_ro("Do unto others as you would have them do to you"); Str8RO s7 = wapp_str8_lit_ro("Do unto others as you would have them do to you");
result = result && wapp_str8_get(&s7, 16) == 's'; result = result && wapp_str8_get(&s7, 16) == 's';
return wapp_tester_result(result); return wapp_tester_result(result);
} }
TestFuncResult test_str8_get_index_out_of_bounds(void) { TestFuncResult test_str8_get_index_out_of_bounds(void) {
Str8 s1 = wapp_str8_lit("Hello world"); Str8 s1 = wapp_str8_lit("Hello world");
b8 result = wapp_str8_get(&s1, 20) == '\0'; b8 result = wapp_str8_get(&s1, 20) == '\0';
return wapp_tester_result(result); return wapp_tester_result(result);
} }
TestFuncResult test_str8_set(void) { TestFuncResult test_str8_set(void) {
b8 result; b8 result;
Str8 s1 = wapp_str8_lit("Hello world"); Str8 s1 = wapp_str8_lit("Hello world");
wapp_str8_set(&s1, 4, 'f'); wapp_str8_set(&s1, 4, 'f');
result = wapp_str8_get(&s1, 4) == 'f'; result = wapp_str8_get(&s1, 4) == 'f';
Str8 s2 = wapp_str8_lit("Different strokes for different folks"); Str8 s2 = wapp_str8_lit("Different strokes for different folks");
wapp_str8_set(&s2, 0, 'A'); wapp_str8_set(&s2, 0, 'A');
result = result && wapp_str8_get(&s2, 0) == 'A'; result = result && wapp_str8_get(&s2, 0) == 'A';
Str8 s3 = wapp_str8_lit("Discretion is the better part of valour"); Str8 s3 = wapp_str8_lit("Discretion is the better part of valour");
wapp_str8_set(&s3, 13, 'u'); wapp_str8_set(&s3, 13, 'u');
result = result && wapp_str8_get(&s3, 13) == 'u'; result = result && wapp_str8_get(&s3, 13) == 'u';
Str8 s4 = wapp_str8_lit("Distance lends enchantment to the view"); Str8 s4 = wapp_str8_lit("Distance lends enchantment to the view");
wapp_str8_set(&s4, 20, 'R'); wapp_str8_set(&s4, 20, 'R');
result = result && wapp_str8_get(&s4, 20) == 'R'; result = result && wapp_str8_get(&s4, 20) == 'R';
Str8 s5 = wapp_str8_lit("Do as I say, not as I do"); Str8 s5 = wapp_str8_lit("Do as I say, not as I do");
wapp_str8_set(&s5, 11, '.'); wapp_str8_set(&s5, 11, '.');
result = result && wapp_str8_get(&s5, 11) == '.'; result = result && wapp_str8_get(&s5, 11) == '.';
Str8 s6 = wapp_str8_lit("Do as you would be done by"); Str8 s6 = wapp_str8_lit("Do as you would be done by");
wapp_str8_set(&s6, 25, 'w'); wapp_str8_set(&s6, 25, 'w');
result = result && wapp_str8_get(&s6, 25) == 'w'; result = result && wapp_str8_get(&s6, 25) == 'w';
Str8 s7 = wapp_str8_lit("Do unto others as you would have them do to you"); Str8 s7 = wapp_str8_lit("Do unto others as you would have them do to you");
wapp_str8_set(&s7, 16, 'i'); wapp_str8_set(&s7, 16, 'i');
result = result && wapp_str8_get(&s7, 16) == 'i'; result = result && wapp_str8_get(&s7, 16) == 'i';
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -234,8 +234,8 @@ TestFuncResult test_str8_set(void) {
TestFuncResult test_str8_push_back(void) { TestFuncResult test_str8_push_back(void) {
b8 result; b8 result;
Str8 expected = wapp_str8_lit("Abdelrahman"); Str8 expected = wapp_str8_lit("Abdelrahman");
Str8 buf = wapp_str8_buf(64); Str8 buf = wapp_str8_buf(64);
wapp_str8_push_back(&buf, 'A'); wapp_str8_push_back(&buf, 'A');
wapp_str8_push_back(&buf, 'b'); wapp_str8_push_back(&buf, 'b');
wapp_str8_push_back(&buf, 'd'); wapp_str8_push_back(&buf, 'd');
@@ -291,11 +291,11 @@ TestFuncResult test_str8_alloc_concat(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KiB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("Hello world"); Str8 str = wapp_str8_lit("Hello world");
Str8 suffix1 = wapp_str8_lit(" from me."); Str8 suffix1 = wapp_str8_lit(" from me.");
Str8 suffix2 = wapp_str8_lit(" This is my code."); Str8 suffix2 = wapp_str8_lit(" This is my code.");
Str8 concat1 = wapp_str8_lit("Hello world from me."); Str8 concat1 = wapp_str8_lit("Hello world from me.");
Str8 concat2 = wapp_str8_lit("Hello world from me. This is my code."); Str8 concat2 = wapp_str8_lit("Hello world from me. This is my code.");
Str8 *output; Str8 *output;
@@ -313,11 +313,11 @@ TestFuncResult test_str8_alloc_concat(void) {
TestFuncResult test_str8_concat_capped(void) { TestFuncResult test_str8_concat_capped(void) {
b8 result; b8 result;
Str8 str = wapp_str8_lit("Hello world"); Str8 str = wapp_str8_lit("Hello world");
Str8 suffix1 = wapp_str8_lit(" from me."); Str8 suffix1 = wapp_str8_lit(" from me.");
Str8 suffix2 = wapp_str8_lit(" This is my code."); Str8 suffix2 = wapp_str8_lit(" This is my code.");
Str8 concat1 = wapp_str8_lit("Hello world from me."); Str8 concat1 = wapp_str8_lit("Hello world from me.");
Str8 concat2 = wapp_str8_lit("Hello world from me. T"); Str8 concat2 = wapp_str8_lit("Hello world from me. T");
wapp_str8_concat_capped(&str, &suffix1); wapp_str8_concat_capped(&str, &suffix1);
result = str.size == concat1.size && wapp_str8_equal(&str, &concat1); result = str.size == concat1.size && wapp_str8_equal(&str, &concat1);
@@ -331,11 +331,11 @@ TestFuncResult test_str8_concat_capped(void) {
TestFuncResult test_str8_copy_cstr_capped(void) { TestFuncResult test_str8_copy_cstr_capped(void) {
b8 result; b8 result;
Str8 buf = wapp_str8_buf(32); Str8 buf = wapp_str8_buf(32);
const char *src1 = "Hello world"; const char *src1 = "Hello world";
const char *src2 = "Hello world from the Wizard Apprentice standard library"; const char *src2 = "Hello world from the Wizard Apprentice standard library";
Str8RO src1_cp = wapp_str8_lit_ro("Hello world"); Str8RO src1_cp = wapp_str8_lit_ro("Hello world");
Str8RO src2_cp = wapp_str8_lit_ro("Hello world from the Wizard Appr"); Str8RO src2_cp = wapp_str8_lit_ro("Hello world from the Wizard Appr");
wapp_str8_copy_cstr_capped(&buf, src1); wapp_str8_copy_cstr_capped(&buf, src1);
result = buf.size == src1_cp.size && wapp_str8_equal(&buf, &src1_cp); result = buf.size == src1_cp.size && wapp_str8_equal(&buf, &src1_cp);
@@ -349,10 +349,10 @@ TestFuncResult test_str8_copy_cstr_capped(void) {
TestFuncResult test_str8_copy_str8_capped(void) { TestFuncResult test_str8_copy_str8_capped(void) {
b8 result; b8 result;
Str8 buf = wapp_str8_buf(32); Str8 buf = wapp_str8_buf(32);
Str8RO src1 = wapp_str8_lit_ro("Hello world"); Str8RO src1 = wapp_str8_lit_ro("Hello world");
Str8RO src2 = wapp_str8_lit_ro("Hello world from the Wizard Apprentice standard library"); Str8RO src2 = wapp_str8_lit_ro("Hello world from the Wizard Apprentice standard library");
Str8RO src2_cp = wapp_str8_lit_ro("Hello world from the Wizard Appr"); Str8RO src2_cp = wapp_str8_lit_ro("Hello world from the Wizard Appr");
wapp_str8_copy_str8_capped(&buf, &src1); wapp_str8_copy_str8_capped(&buf, &src1);
result = buf.size == src1.size && wapp_str8_equal(&buf, &src1); result = buf.size == src1.size && wapp_str8_equal(&buf, &src1);
@@ -366,8 +366,8 @@ TestFuncResult test_str8_copy_str8_capped(void) {
TestFuncResult test_str8_format(void) { TestFuncResult test_str8_format(void) {
b8 result; b8 result;
Str8 buf = wapp_str8_buf(128); Str8 buf = wapp_str8_buf(128);
Str8 expected = wapp_str8_lit("My name is Abdelrahman and I am 35 years old"); Str8 expected = wapp_str8_lit("My name is Abdelrahman and I am 35 years old");
wapp_str8_format(&buf, "My name is %s and I am %u years old", "Abdelrahman", 35); wapp_str8_format(&buf, "My name is %s and I am %u years old", "Abdelrahman", 35);
@@ -412,11 +412,11 @@ TestFuncResult test_str8_split(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KiB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim1 = wapp_str8_lit(" "); Str8 delim1 = wapp_str8_lit(" ");
Str8 delim2 = wapp_str8_lit("from"); Str8 delim2 = wapp_str8_lit("from");
Str8List *list1 = wapp_str8_split(&arena, &str, &delim1); Str8List *list1 = wapp_str8_split(&arena, &str, &delim1);
Str8List *list2 = wapp_str8_split(&arena, &str, &delim2); Str8List *list2 = wapp_str8_split(&arena, &str, &delim2);
Str8RO splits1[] = { Str8RO splits1[] = {
wapp_str8_slice(&str, 0, 5), wapp_str8_slice(&str, 0, 5),
@@ -429,13 +429,13 @@ TestFuncResult test_str8_split(void) {
wapp_str8_slice(&str, 16, 19), wapp_str8_slice(&str, 16, 19),
}; };
u64 index1 = 0; u64 index1 = 0;
u64 count1 = ARRLEN(splits1); u64 count1 = ARRLEN(splits1);
b8 running1 = true; b8 running1 = true;
u64 index2 = 0; u64 index2 = 0;
u64 count2 = ARRLEN(splits2); u64 count2 = ARRLEN(splits2);
b8 running2 = true; b8 running2 = true;
result = list1->node_count == count1 && wapp_str8_list_total_size(list1) == str.size - 3; result = list1->node_count == count1 && wapp_str8_list_total_size(list1) == str.size - 3;
result = result && list2->node_count == count2 && wapp_str8_list_total_size(list2) == str.size - 4; result = result && list2->node_count == count2 && wapp_str8_list_total_size(list2) == str.size - 4;
@@ -443,8 +443,8 @@ TestFuncResult test_str8_split(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running1) { while (running1) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list1, index1); Str8 *node = wapp_dbl_list_get(Str8, list1, index1);
result = result && wapp_str8_equal(node->item, &(splits1[index1])); result = result && wapp_str8_equal(node, &(splits1[index1]));
++index1; ++index1;
running1 = index1 < count1; running1 = index1 < count1;
@@ -453,8 +453,8 @@ TestFuncResult test_str8_split(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running2) { while (running2) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list2, index2); Str8 *node = wapp_dbl_list_get(Str8, list2, index2);
result = result && wapp_str8_equal(node->item, &(splits2[index2])); result = result && wapp_str8_equal(node, &(splits2[index2]));
++index2; ++index2;
running2 = index2 < count2; running2 = index2 < count2;
@@ -469,9 +469,9 @@ TestFuncResult test_str8_split_with_max(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KiB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim = wapp_str8_lit(" "); Str8 delim = wapp_str8_lit(" ");
Str8List *list = wapp_str8_split_with_max(&arena, &str, &delim, 2); Str8List *list = wapp_str8_split_with_max(&arena, &str, &delim, 2);
Str8RO splits[] = { Str8RO splits[] = {
wapp_str8_slice(&str, 0, 5), wapp_str8_slice(&str, 0, 5),
@@ -479,17 +479,17 @@ TestFuncResult test_str8_split_with_max(void) {
wapp_str8_slice(&str, 12, 19), wapp_str8_slice(&str, 12, 19),
}; };
u64 index = 0; u64 index = 0;
u64 count = ARRLEN(splits); u64 count = ARRLEN(splits);
b8 running = true; b8 running = true;
result = list->node_count == count && wapp_str8_list_total_size(list) == str.size - 2; result = list->node_count == count && wapp_str8_list_total_size(list) == str.size - 2;
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running) { while (running) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list, index); Str8 *node = wapp_dbl_list_get(Str8, list, index);
result = result && wapp_str8_equal(node->item, &(splits[index])); result = result && wapp_str8_equal(node, &(splits[index]));
++index; ++index;
running = index < count; running = index < count;
@@ -504,11 +504,11 @@ TestFuncResult test_str8_rsplit(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KiB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim1 = wapp_str8_lit(" "); Str8 delim1 = wapp_str8_lit(" ");
Str8 delim2 = wapp_str8_lit("from"); Str8 delim2 = wapp_str8_lit("from");
Str8List *list1 = wapp_str8_rsplit(&arena, &str, &delim1); Str8List *list1 = wapp_str8_rsplit(&arena, &str, &delim1);
Str8List *list2 = wapp_str8_rsplit(&arena, &str, &delim2); Str8List *list2 = wapp_str8_rsplit(&arena, &str, &delim2);
Str8RO splits1[] = { Str8RO splits1[] = {
wapp_str8_slice(&str, 0, 5), wapp_str8_slice(&str, 0, 5),
@@ -521,13 +521,13 @@ TestFuncResult test_str8_rsplit(void) {
wapp_str8_slice(&str, 16, 19), wapp_str8_slice(&str, 16, 19),
}; };
u64 index1 = 0; u64 index1 = 0;
u64 count1 = ARRLEN(splits1); u64 count1 = ARRLEN(splits1);
b8 running1 = true; b8 running1 = true;
u64 index2 = 0; u64 index2 = 0;
u64 count2 = ARRLEN(splits2); u64 count2 = ARRLEN(splits2);
b8 running2 = true; b8 running2 = true;
result = list1->node_count == count1 && wapp_str8_list_total_size(list1) == str.size - 3; result = list1->node_count == count1 && wapp_str8_list_total_size(list1) == str.size - 3;
result = result && list2->node_count == count2 && wapp_str8_list_total_size(list2) == str.size - 4; result = result && list2->node_count == count2 && wapp_str8_list_total_size(list2) == str.size - 4;
@@ -535,8 +535,8 @@ TestFuncResult test_str8_rsplit(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running1) { while (running1) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list1, index1); Str8 *node = wapp_dbl_list_get(Str8, list1, index1);
result = result && wapp_str8_equal(node->item, &(splits1[index1])); result = result && wapp_str8_equal(node, &(splits1[index1]));
++index1; ++index1;
running1 = index1 < count1; running1 = index1 < count1;
@@ -545,8 +545,8 @@ TestFuncResult test_str8_rsplit(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running2) { while (running2) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list2, index2); Str8 *node = wapp_dbl_list_get(Str8, list2, index2);
result = result && wapp_str8_equal(node->item, &(splits2[index2])); result = result && wapp_str8_equal(node, &(splits2[index2]));
++index2; ++index2;
running2 = index2 < count2; running2 = index2 < count2;
@@ -561,9 +561,9 @@ TestFuncResult test_str8_rsplit_with_max(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KiB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim = wapp_str8_lit(" "); Str8 delim = wapp_str8_lit(" ");
Str8List *list = wapp_str8_rsplit_with_max(&arena, &str, &delim, 2); Str8List *list = wapp_str8_rsplit_with_max(&arena, &str, &delim, 2);
Str8RO splits[] = { Str8RO splits[] = {
wapp_str8_slice(&str, 0, 11), wapp_str8_slice(&str, 0, 11),
@@ -571,17 +571,17 @@ TestFuncResult test_str8_rsplit_with_max(void) {
wapp_str8_slice(&str, 17, 19), wapp_str8_slice(&str, 17, 19),
}; };
u64 index = 0; u64 index = 0;
u64 count = ARRLEN(splits); u64 count = ARRLEN(splits);
b8 running = true; b8 running = true;
result = list->node_count == count && wapp_str8_list_total_size(list) == str.size - 2; result = list->node_count == count && wapp_str8_list_total_size(list) == str.size - 2;
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running) { while (running) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list, index); Str8 *node = wapp_dbl_list_get(Str8, list, index);
result = result && wapp_str8_equal(node->item, &(splits[index])); result = result && wapp_str8_equal(node, &(splits[index]));
++index; ++index;
running = index < count; running = index < count;
@@ -596,13 +596,13 @@ TestFuncResult test_str8_join(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KiB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim1 = wapp_str8_lit(" "); Str8 delim1 = wapp_str8_lit(" ");
Str8 delim2 = wapp_str8_lit("from"); Str8 delim2 = wapp_str8_lit("from");
Str8List *list1 = wapp_str8_rsplit(&arena, &str, &delim1); Str8List *list1 = wapp_str8_rsplit(&arena, &str, &delim1);
Str8List *list2 = wapp_str8_rsplit(&arena, &str, &delim2); Str8List *list2 = wapp_str8_rsplit(&arena, &str, &delim2);
Str8 *join1 = wapp_str8_join(&arena, list1, &delim1); Str8 *join1 = wapp_str8_join(&arena, list1, &delim1);
Str8 *join2 = wapp_str8_join(&arena, list2, &delim2); Str8 *join2 = wapp_str8_join(&arena, list2, &delim2);
result = join1->size == str.size && wapp_str8_equal(join1, &str); result = join1->size == str.size && wapp_str8_equal(join1, &str);
result = result && join2->size == str.size && wapp_str8_equal(join2, &str); result = result && join2->size == str.size && wapp_str8_equal(join2, &str);
@@ -615,11 +615,11 @@ TestFuncResult test_str8_join(void) {
TestFuncResult test_str8_from_bytes(void) { TestFuncResult test_str8_from_bytes(void) {
b8 result; b8 result;
Str8 str = wapp_str8_buf(1024); Str8 str = wapp_str8_buf(1024);
U8Array bytes = wapp_array(u8, U8Array, 'W', 'A', 'P', 'P'); U8Array bytes = wapp_array(u8, 'W', 'A', 'P', 'P');
wapp_str8_from_bytes(&str, &bytes); wapp_str8_from_bytes(&str, bytes);
result = str.size == bytes.count * bytes.item_size; result = str.size == wapp_array_count(bytes) * wapp_array_item_size(bytes);
result = result && wapp_str8_equal(&str, &wapp_str8_lit_ro("WAPP")); result = result && wapp_str8_equal(&str, &wapp_str8_lit_ro("WAPP"));
return wapp_tester_result(result); return wapp_tester_result(result);

View File

@@ -6,26 +6,26 @@
TestFuncResult test_str8_lit(void) { TestFuncResult test_str8_lit(void) {
b8 result; b8 result;
Str8 s1 = wapp_str8_lit("Hello world"); Str8 s1 = wapp_str8_lit("Hello world");
result = s1.capacity == 22 && s1.capacity != s1.size; result = s1.capacity == 22 && s1.capacity != s1.size;
Str8 s2 = wapp_str8_lit("Different strokes for different folks"); Str8 s2 = wapp_str8_lit("Different strokes for different folks");
result = result && s2.capacity == 74 && s2.capacity != s2.size; result = result && s2.capacity == 74 && s2.capacity != s2.size;
Str8 s3 = wapp_str8_lit("Discretion is the better part of valour"); Str8 s3 = wapp_str8_lit("Discretion is the better part of valour");
result = result && s3.capacity == 78 && s3.capacity != s3.size; result = result && s3.capacity == 78 && s3.capacity != s3.size;
Str8 s4 = wapp_str8_lit("Distance lends enchantment to the view"); Str8 s4 = wapp_str8_lit("Distance lends enchantment to the view");
result = result && s4.capacity == 76 && s4.capacity != s4.size; result = result && s4.capacity == 76 && s4.capacity != s4.size;
Str8 s5 = wapp_str8_lit("Do as I say, not as I do"); Str8 s5 = wapp_str8_lit("Do as I say, not as I do");
result = result && s5.capacity == 48 && s5.capacity != s5.size; result = result && s5.capacity == 48 && s5.capacity != s5.size;
Str8 s6 = wapp_str8_lit("Do as you would be done by"); Str8 s6 = wapp_str8_lit("Do as you would be done by");
result = result && s6.capacity == 52 && s6.capacity != s6.size; result = result && s6.capacity == 52 && s6.capacity != s6.size;
Str8 s7 = wapp_str8_lit("Do unto others as you would have them do to you"); Str8 s7 = wapp_str8_lit("Do unto others as you would have them do to you");
result = result && s7.capacity == 94 && s7.capacity != s7.size; result = result && s7.capacity == 94 && s7.capacity != s7.size;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -33,26 +33,26 @@ TestFuncResult test_str8_lit(void) {
TestFuncResult test_str8_lit_ro(void) { TestFuncResult test_str8_lit_ro(void) {
b8 result; b8 result;
Str8RO s1 = wapp_str8_lit_ro("Hello world"); Str8RO s1 = wapp_str8_lit_ro("Hello world");
result = s1.capacity == 11 && s1.capacity == s1.size; result = s1.capacity == 11 && s1.capacity == s1.size;
Str8RO s2 = wapp_str8_lit_ro("Different strokes for different folks"); Str8RO s2 = wapp_str8_lit_ro("Different strokes for different folks");
result = result && s2.capacity == 37 && s2.capacity == s2.size; result = result && s2.capacity == 37 && s2.capacity == s2.size;
Str8RO s3 = wapp_str8_lit_ro("Discretion is the better part of valour"); Str8RO s3 = wapp_str8_lit_ro("Discretion is the better part of valour");
result = result && s3.capacity == 39 && s3.capacity == s3.size; result = result && s3.capacity == 39 && s3.capacity == s3.size;
Str8RO s4 = wapp_str8_lit_ro("Distance lends enchantment to the view"); Str8RO s4 = wapp_str8_lit_ro("Distance lends enchantment to the view");
result = result && s4.capacity == 38 && s4.capacity == s4.size; result = result && s4.capacity == 38 && s4.capacity == s4.size;
Str8RO s5 = wapp_str8_lit_ro("Do as I say, not as I do"); Str8RO s5 = wapp_str8_lit_ro("Do as I say, not as I do");
result = result && s5.capacity == 24 && s5.capacity == s5.size; result = result && s5.capacity == 24 && s5.capacity == s5.size;
Str8RO s6 = wapp_str8_lit_ro("Do as you would be done by"); Str8RO s6 = wapp_str8_lit_ro("Do as you would be done by");
result = result && s6.capacity == 26 && s6.capacity == s6.size; result = result && s6.capacity == 26 && s6.capacity == s6.size;
Str8RO s7 = wapp_str8_lit_ro("Do unto others as you would have them do to you"); Str8RO s7 = wapp_str8_lit_ro("Do unto others as you would have them do to you");
result = result && s7.capacity == 47 && s7.capacity == s7.size; result = result && s7.capacity == 47 && s7.capacity == s7.size;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -60,17 +60,17 @@ TestFuncResult test_str8_lit_ro(void) {
TestFuncResult test_str8_buf(void) { TestFuncResult test_str8_buf(void) {
b8 result; b8 result;
Str8 s1 = wapp_str8_buf(1024); Str8 s1 = wapp_str8_buf(1024);
result = s1.capacity == 1024 && s1.size == 0; result = s1.capacity == 1024 && s1.size == 0;
Str8 s2 = wapp_str8_buf(2048); Str8 s2 = wapp_str8_buf(2048);
result = result && s2.capacity == 2048 && s2.size == 0; result = result && s2.capacity == 2048 && s2.size == 0;
Str8 s3 = wapp_str8_buf(4096); Str8 s3 = wapp_str8_buf(4096);
result = result && s3.capacity == 4096 && s3.size == 0; result = result && s3.capacity == 4096 && s3.size == 0;
Str8 s4 = wapp_str8_buf(8192); Str8 s4 = wapp_str8_buf(8192);
result = result && s4.capacity == 8192 && s4.size == 0; result = result && s4.capacity == 8192 && s4.size == 0;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -91,7 +91,7 @@ TestFuncResult test_str8_alloc_buf(void) {
return wapp_tester_result(result); return wapp_tester_result(result);
} }
result = s->capacity == capacity; result = s->capacity == capacity;
const char *cstr = "My name is Abdelrahman"; const char *cstr = "My name is Abdelrahman";
wapp_str8_copy_cstr_capped(s, cstr); wapp_str8_copy_cstr_capped(s, cstr);
@@ -110,9 +110,9 @@ TestFuncResult test_str8_alloc_cstr(void) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
const char *str = "Abdelrahman"; const char *str = "Abdelrahman";
u64 length = strlen(str); u64 length = strlen(str);
Str8 *s = wapp_str8_alloc_cstr(&allocator, str); Str8 *s = wapp_str8_alloc_cstr(&allocator, str);
if (!s) { if (!s) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
@@ -131,8 +131,8 @@ TestFuncResult test_str8_alloc_str8(void) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
Str8 str = wapp_str8_lit("Abdelrahman"); Str8 str = wapp_str8_lit("Abdelrahman");
Str8 *s = wapp_str8_alloc_str8(&allocator, &str); Str8 *s = wapp_str8_alloc_str8(&allocator, &str);
if (!s) { if (!s) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
@@ -151,8 +151,8 @@ TestFuncResult test_str8_alloc_substr(void) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
Str8 str = wapp_str8_lit("Abdelrahman"); Str8 str = wapp_str8_lit("Abdelrahman");
Str8 *s = wapp_str8_alloc_substr(&allocator, &str, 3, 8); Str8 *s = wapp_str8_alloc_substr(&allocator, &str, 3, 8);
if (!s) { if (!s) {
return wapp_tester_result(false); return wapp_tester_result(false);
} }
@@ -167,66 +167,66 @@ TestFuncResult test_str8_alloc_substr(void) {
TestFuncResult test_str8_get_index_within_bounds(void) { TestFuncResult test_str8_get_index_within_bounds(void) {
b8 result; b8 result;
Str8RO s1 = wapp_str8_lit_ro("Hello world"); Str8RO s1 = wapp_str8_lit_ro("Hello world");
result = wapp_str8_get(&s1, 4) == 'o'; result = wapp_str8_get(&s1, 4) == 'o';
Str8RO s2 = wapp_str8_lit_ro("Different strokes for different folks"); Str8RO s2 = wapp_str8_lit_ro("Different strokes for different folks");
result = result && wapp_str8_get(&s2, 0) == 'D'; result = result && wapp_str8_get(&s2, 0) == 'D';
Str8RO s3 = wapp_str8_lit_ro("Discretion is the better part of valour"); Str8RO s3 = wapp_str8_lit_ro("Discretion is the better part of valour");
result = result && wapp_str8_get(&s3, 13) == ' '; result = result && wapp_str8_get(&s3, 13) == ' ';
Str8RO s4 = wapp_str8_lit_ro("Distance lends enchantment to the view"); Str8RO s4 = wapp_str8_lit_ro("Distance lends enchantment to the view");
result = result && wapp_str8_get(&s4, 20) == 'n'; result = result && wapp_str8_get(&s4, 20) == 'n';
Str8RO s5 = wapp_str8_lit_ro("Do as I say, not as I do"); Str8RO s5 = wapp_str8_lit_ro("Do as I say, not as I do");
result = result && wapp_str8_get(&s5, 11) == ','; result = result && wapp_str8_get(&s5, 11) == ',';
Str8RO s6 = wapp_str8_lit_ro("Do as you would be done by"); Str8RO s6 = wapp_str8_lit_ro("Do as you would be done by");
result = result && wapp_str8_get(&s6, 25) == 'y'; result = result && wapp_str8_get(&s6, 25) == 'y';
Str8RO s7 = wapp_str8_lit_ro("Do unto others as you would have them do to you"); Str8RO s7 = wapp_str8_lit_ro("Do unto others as you would have them do to you");
result = result && wapp_str8_get(&s7, 16) == 's'; result = result && wapp_str8_get(&s7, 16) == 's';
return wapp_tester_result(result); return wapp_tester_result(result);
} }
TestFuncResult test_str8_get_index_out_of_bounds(void) { TestFuncResult test_str8_get_index_out_of_bounds(void) {
Str8 s1 = wapp_str8_lit("Hello world"); Str8 s1 = wapp_str8_lit("Hello world");
b8 result = wapp_str8_get(&s1, 20) == '\0'; b8 result = wapp_str8_get(&s1, 20) == '\0';
return wapp_tester_result(result); return wapp_tester_result(result);
} }
TestFuncResult test_str8_set(void) { TestFuncResult test_str8_set(void) {
b8 result; b8 result;
Str8 s1 = wapp_str8_lit("Hello world"); Str8 s1 = wapp_str8_lit("Hello world");
wapp_str8_set(&s1, 4, 'f'); wapp_str8_set(&s1, 4, 'f');
result = wapp_str8_get(&s1, 4) == 'f'; result = wapp_str8_get(&s1, 4) == 'f';
Str8 s2 = wapp_str8_lit("Different strokes for different folks"); Str8 s2 = wapp_str8_lit("Different strokes for different folks");
wapp_str8_set(&s2, 0, 'A'); wapp_str8_set(&s2, 0, 'A');
result = result && wapp_str8_get(&s2, 0) == 'A'; result = result && wapp_str8_get(&s2, 0) == 'A';
Str8 s3 = wapp_str8_lit("Discretion is the better part of valour"); Str8 s3 = wapp_str8_lit("Discretion is the better part of valour");
wapp_str8_set(&s3, 13, 'u'); wapp_str8_set(&s3, 13, 'u');
result = result && wapp_str8_get(&s3, 13) == 'u'; result = result && wapp_str8_get(&s3, 13) == 'u';
Str8 s4 = wapp_str8_lit("Distance lends enchantment to the view"); Str8 s4 = wapp_str8_lit("Distance lends enchantment to the view");
wapp_str8_set(&s4, 20, 'R'); wapp_str8_set(&s4, 20, 'R');
result = result && wapp_str8_get(&s4, 20) == 'R'; result = result && wapp_str8_get(&s4, 20) == 'R';
Str8 s5 = wapp_str8_lit("Do as I say, not as I do"); Str8 s5 = wapp_str8_lit("Do as I say, not as I do");
wapp_str8_set(&s5, 11, '.'); wapp_str8_set(&s5, 11, '.');
result = result && wapp_str8_get(&s5, 11) == '.'; result = result && wapp_str8_get(&s5, 11) == '.';
Str8 s6 = wapp_str8_lit("Do as you would be done by"); Str8 s6 = wapp_str8_lit("Do as you would be done by");
wapp_str8_set(&s6, 25, 'w'); wapp_str8_set(&s6, 25, 'w');
result = result && wapp_str8_get(&s6, 25) == 'w'; result = result && wapp_str8_get(&s6, 25) == 'w';
Str8 s7 = wapp_str8_lit("Do unto others as you would have them do to you"); Str8 s7 = wapp_str8_lit("Do unto others as you would have them do to you");
wapp_str8_set(&s7, 16, 'i'); wapp_str8_set(&s7, 16, 'i');
result = result && wapp_str8_get(&s7, 16) == 'i'; result = result && wapp_str8_get(&s7, 16) == 'i';
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -234,8 +234,8 @@ TestFuncResult test_str8_set(void) {
TestFuncResult test_str8_push_back(void) { TestFuncResult test_str8_push_back(void) {
b8 result; b8 result;
Str8 expected = wapp_str8_lit("Abdelrahman"); Str8 expected = wapp_str8_lit("Abdelrahman");
Str8 buf = wapp_str8_buf(64); Str8 buf = wapp_str8_buf(64);
wapp_str8_push_back(&buf, 'A'); wapp_str8_push_back(&buf, 'A');
wapp_str8_push_back(&buf, 'b'); wapp_str8_push_back(&buf, 'b');
wapp_str8_push_back(&buf, 'd'); wapp_str8_push_back(&buf, 'd');
@@ -291,11 +291,11 @@ TestFuncResult test_str8_alloc_concat(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KiB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("Hello world"); Str8 str = wapp_str8_lit("Hello world");
Str8 suffix1 = wapp_str8_lit(" from me."); Str8 suffix1 = wapp_str8_lit(" from me.");
Str8 suffix2 = wapp_str8_lit(" This is my code."); Str8 suffix2 = wapp_str8_lit(" This is my code.");
Str8 concat1 = wapp_str8_lit("Hello world from me."); Str8 concat1 = wapp_str8_lit("Hello world from me.");
Str8 concat2 = wapp_str8_lit("Hello world from me. This is my code."); Str8 concat2 = wapp_str8_lit("Hello world from me. This is my code.");
Str8 *output; Str8 *output;
@@ -313,11 +313,11 @@ TestFuncResult test_str8_alloc_concat(void) {
TestFuncResult test_str8_concat_capped(void) { TestFuncResult test_str8_concat_capped(void) {
b8 result; b8 result;
Str8 str = wapp_str8_lit("Hello world"); Str8 str = wapp_str8_lit("Hello world");
Str8 suffix1 = wapp_str8_lit(" from me."); Str8 suffix1 = wapp_str8_lit(" from me.");
Str8 suffix2 = wapp_str8_lit(" This is my code."); Str8 suffix2 = wapp_str8_lit(" This is my code.");
Str8 concat1 = wapp_str8_lit("Hello world from me."); Str8 concat1 = wapp_str8_lit("Hello world from me.");
Str8 concat2 = wapp_str8_lit("Hello world from me. T"); Str8 concat2 = wapp_str8_lit("Hello world from me. T");
wapp_str8_concat_capped(&str, &suffix1); wapp_str8_concat_capped(&str, &suffix1);
result = str.size == concat1.size && wapp_str8_equal(&str, &concat1); result = str.size == concat1.size && wapp_str8_equal(&str, &concat1);
@@ -331,11 +331,11 @@ TestFuncResult test_str8_concat_capped(void) {
TestFuncResult test_str8_copy_cstr_capped(void) { TestFuncResult test_str8_copy_cstr_capped(void) {
b8 result; b8 result;
Str8 buf = wapp_str8_buf(32); Str8 buf = wapp_str8_buf(32);
const char *src1 = "Hello world"; const char *src1 = "Hello world";
const char *src2 = "Hello world from the Wizard Apprentice standard library"; const char *src2 = "Hello world from the Wizard Apprentice standard library";
Str8RO src1_cp = wapp_str8_lit_ro("Hello world"); Str8RO src1_cp = wapp_str8_lit_ro("Hello world");
Str8RO src2_cp = wapp_str8_lit_ro("Hello world from the Wizard Appr"); Str8RO src2_cp = wapp_str8_lit_ro("Hello world from the Wizard Appr");
wapp_str8_copy_cstr_capped(&buf, src1); wapp_str8_copy_cstr_capped(&buf, src1);
result = buf.size == src1_cp.size && wapp_str8_equal(&buf, &src1_cp); result = buf.size == src1_cp.size && wapp_str8_equal(&buf, &src1_cp);
@@ -349,10 +349,10 @@ TestFuncResult test_str8_copy_cstr_capped(void) {
TestFuncResult test_str8_copy_str8_capped(void) { TestFuncResult test_str8_copy_str8_capped(void) {
b8 result; b8 result;
Str8 buf = wapp_str8_buf(32); Str8 buf = wapp_str8_buf(32);
Str8RO src1 = wapp_str8_lit_ro("Hello world"); Str8RO src1 = wapp_str8_lit_ro("Hello world");
Str8RO src2 = wapp_str8_lit_ro("Hello world from the Wizard Apprentice standard library"); Str8RO src2 = wapp_str8_lit_ro("Hello world from the Wizard Apprentice standard library");
Str8RO src2_cp = wapp_str8_lit_ro("Hello world from the Wizard Appr"); Str8RO src2_cp = wapp_str8_lit_ro("Hello world from the Wizard Appr");
wapp_str8_copy_str8_capped(&buf, &src1); wapp_str8_copy_str8_capped(&buf, &src1);
result = buf.size == src1.size && wapp_str8_equal(&buf, &src1); result = buf.size == src1.size && wapp_str8_equal(&buf, &src1);
@@ -366,8 +366,8 @@ TestFuncResult test_str8_copy_str8_capped(void) {
TestFuncResult test_str8_format(void) { TestFuncResult test_str8_format(void) {
b8 result; b8 result;
Str8 buf = wapp_str8_buf(128); Str8 buf = wapp_str8_buf(128);
Str8 expected = wapp_str8_lit("My name is Abdelrahman and I am 35 years old"); Str8 expected = wapp_str8_lit("My name is Abdelrahman and I am 35 years old");
wapp_str8_format(&buf, "My name is %s and I am %u years old", "Abdelrahman", 35); wapp_str8_format(&buf, "My name is %s and I am %u years old", "Abdelrahman", 35);
@@ -412,11 +412,11 @@ TestFuncResult test_str8_split(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KiB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim1 = wapp_str8_lit(" "); Str8 delim1 = wapp_str8_lit(" ");
Str8 delim2 = wapp_str8_lit("from"); Str8 delim2 = wapp_str8_lit("from");
Str8List *list1 = wapp_str8_split(&arena, &str, &delim1); Str8List *list1 = wapp_str8_split(&arena, &str, &delim1);
Str8List *list2 = wapp_str8_split(&arena, &str, &delim2); Str8List *list2 = wapp_str8_split(&arena, &str, &delim2);
Str8RO splits1[] = { Str8RO splits1[] = {
wapp_str8_slice(&str, 0, 5), wapp_str8_slice(&str, 0, 5),
@@ -429,13 +429,13 @@ TestFuncResult test_str8_split(void) {
wapp_str8_slice(&str, 16, 19), wapp_str8_slice(&str, 16, 19),
}; };
u64 index1 = 0; u64 index1 = 0;
u64 count1 = ARRLEN(splits1); u64 count1 = ARRLEN(splits1);
b8 running1 = true; b8 running1 = true;
u64 index2 = 0; u64 index2 = 0;
u64 count2 = ARRLEN(splits2); u64 count2 = ARRLEN(splits2);
b8 running2 = true; b8 running2 = true;
result = list1->node_count == count1 && wapp_str8_list_total_size(list1) == str.size - 3; result = list1->node_count == count1 && wapp_str8_list_total_size(list1) == str.size - 3;
result = result && list2->node_count == count2 && wapp_str8_list_total_size(list2) == str.size - 4; result = result && list2->node_count == count2 && wapp_str8_list_total_size(list2) == str.size - 4;
@@ -443,8 +443,8 @@ TestFuncResult test_str8_split(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running1) { while (running1) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list1, index1); Str8 *node = wapp_dbl_list_get(Str8, list1, index1);
result = result && wapp_str8_equal(node->item, &(splits1[index1])); result = result && wapp_str8_equal(node, &(splits1[index1]));
++index1; ++index1;
running1 = index1 < count1; running1 = index1 < count1;
@@ -453,8 +453,8 @@ TestFuncResult test_str8_split(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running2) { while (running2) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list2, index2); Str8 *node = wapp_dbl_list_get(Str8, list2, index2);
result = result && wapp_str8_equal(node->item, &(splits2[index2])); result = result && wapp_str8_equal(node, &(splits2[index2]));
++index2; ++index2;
running2 = index2 < count2; running2 = index2 < count2;
@@ -469,9 +469,9 @@ TestFuncResult test_str8_split_with_max(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KiB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim = wapp_str8_lit(" "); Str8 delim = wapp_str8_lit(" ");
Str8List *list = wapp_str8_split_with_max(&arena, &str, &delim, 2); Str8List *list = wapp_str8_split_with_max(&arena, &str, &delim, 2);
Str8RO splits[] = { Str8RO splits[] = {
wapp_str8_slice(&str, 0, 5), wapp_str8_slice(&str, 0, 5),
@@ -479,17 +479,17 @@ TestFuncResult test_str8_split_with_max(void) {
wapp_str8_slice(&str, 12, 19), wapp_str8_slice(&str, 12, 19),
}; };
u64 index = 0; u64 index = 0;
u64 count = ARRLEN(splits); u64 count = ARRLEN(splits);
b8 running = true; b8 running = true;
result = list->node_count == count && wapp_str8_list_total_size(list) == str.size - 2; result = list->node_count == count && wapp_str8_list_total_size(list) == str.size - 2;
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running) { while (running) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list, index); Str8 *node = wapp_dbl_list_get(Str8, list, index);
result = result && wapp_str8_equal(node->item, &(splits[index])); result = result && wapp_str8_equal(node, &(splits[index]));
++index; ++index;
running = index < count; running = index < count;
@@ -504,11 +504,11 @@ TestFuncResult test_str8_rsplit(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KiB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim1 = wapp_str8_lit(" "); Str8 delim1 = wapp_str8_lit(" ");
Str8 delim2 = wapp_str8_lit("from"); Str8 delim2 = wapp_str8_lit("from");
Str8List *list1 = wapp_str8_rsplit(&arena, &str, &delim1); Str8List *list1 = wapp_str8_rsplit(&arena, &str, &delim1);
Str8List *list2 = wapp_str8_rsplit(&arena, &str, &delim2); Str8List *list2 = wapp_str8_rsplit(&arena, &str, &delim2);
Str8RO splits1[] = { Str8RO splits1[] = {
wapp_str8_slice(&str, 0, 5), wapp_str8_slice(&str, 0, 5),
@@ -521,13 +521,13 @@ TestFuncResult test_str8_rsplit(void) {
wapp_str8_slice(&str, 16, 19), wapp_str8_slice(&str, 16, 19),
}; };
u64 index1 = 0; u64 index1 = 0;
u64 count1 = ARRLEN(splits1); u64 count1 = ARRLEN(splits1);
b8 running1 = true; b8 running1 = true;
u64 index2 = 0; u64 index2 = 0;
u64 count2 = ARRLEN(splits2); u64 count2 = ARRLEN(splits2);
b8 running2 = true; b8 running2 = true;
result = list1->node_count == count1 && wapp_str8_list_total_size(list1) == str.size - 3; result = list1->node_count == count1 && wapp_str8_list_total_size(list1) == str.size - 3;
result = result && list2->node_count == count2 && wapp_str8_list_total_size(list2) == str.size - 4; result = result && list2->node_count == count2 && wapp_str8_list_total_size(list2) == str.size - 4;
@@ -535,8 +535,8 @@ TestFuncResult test_str8_rsplit(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running1) { while (running1) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list1, index1); Str8 *node = wapp_dbl_list_get(Str8, list1, index1);
result = result && wapp_str8_equal(node->item, &(splits1[index1])); result = result && wapp_str8_equal(node, &(splits1[index1]));
++index1; ++index1;
running1 = index1 < count1; running1 = index1 < count1;
@@ -545,8 +545,8 @@ TestFuncResult test_str8_rsplit(void) {
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running2) { while (running2) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list2, index2); Str8 *node = wapp_dbl_list_get(Str8, list2, index2);
result = result && wapp_str8_equal(node->item, &(splits2[index2])); result = result && wapp_str8_equal(node, &(splits2[index2]));
++index2; ++index2;
running2 = index2 < count2; running2 = index2 < count2;
@@ -561,9 +561,9 @@ TestFuncResult test_str8_rsplit_with_max(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KiB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim = wapp_str8_lit(" "); Str8 delim = wapp_str8_lit(" ");
Str8List *list = wapp_str8_rsplit_with_max(&arena, &str, &delim, 2); Str8List *list = wapp_str8_rsplit_with_max(&arena, &str, &delim, 2);
Str8RO splits[] = { Str8RO splits[] = {
wapp_str8_slice(&str, 0, 11), wapp_str8_slice(&str, 0, 11),
@@ -571,17 +571,17 @@ TestFuncResult test_str8_rsplit_with_max(void) {
wapp_str8_slice(&str, 17, 19), wapp_str8_slice(&str, 17, 19),
}; };
u64 index = 0; u64 index = 0;
u64 count = ARRLEN(splits); u64 count = ARRLEN(splits);
b8 running = true; b8 running = true;
result = list->node_count == count && wapp_str8_list_total_size(list) == str.size - 2; result = list->node_count == count && wapp_str8_list_total_size(list) == str.size - 2;
// NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of // NOTE (Abdelrahman): Uses a while loop instead of a for loop to get rid of
// MSVC Spectre mitigation warnings // MSVC Spectre mitigation warnings
while (running) { while (running) {
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, list, index); Str8 *node = wapp_dbl_list_get(Str8, list, index);
result = result && wapp_str8_equal(node->item, &(splits[index])); result = result && wapp_str8_equal(node, &(splits[index]));
++index; ++index;
running = index < count; running = index < count;
@@ -596,13 +596,13 @@ TestFuncResult test_str8_join(void) {
b8 result; b8 result;
Allocator arena = wapp_mem_arena_allocator_init(KiB(100)); Allocator arena = wapp_mem_arena_allocator_init(KiB(100));
Str8 str = wapp_str8_lit("hello world from me"); Str8 str = wapp_str8_lit("hello world from me");
Str8 delim1 = wapp_str8_lit(" "); Str8 delim1 = wapp_str8_lit(" ");
Str8 delim2 = wapp_str8_lit("from"); Str8 delim2 = wapp_str8_lit("from");
Str8List *list1 = wapp_str8_rsplit(&arena, &str, &delim1); Str8List *list1 = wapp_str8_rsplit(&arena, &str, &delim1);
Str8List *list2 = wapp_str8_rsplit(&arena, &str, &delim2); Str8List *list2 = wapp_str8_rsplit(&arena, &str, &delim2);
Str8 *join1 = wapp_str8_join(&arena, list1, &delim1); Str8 *join1 = wapp_str8_join(&arena, list1, &delim1);
Str8 *join2 = wapp_str8_join(&arena, list2, &delim2); Str8 *join2 = wapp_str8_join(&arena, list2, &delim2);
result = join1->size == str.size && wapp_str8_equal(join1, &str); result = join1->size == str.size && wapp_str8_equal(join1, &str);
result = result && join2->size == str.size && wapp_str8_equal(join2, &str); result = result && join2->size == str.size && wapp_str8_equal(join2, &str);
@@ -615,12 +615,12 @@ TestFuncResult test_str8_join(void) {
TestFuncResult test_str8_from_bytes(void) { TestFuncResult test_str8_from_bytes(void) {
b8 result; b8 result;
Str8 str = wapp_str8_buf(1024); Str8 str = wapp_str8_buf(1024);
Str8 expected = wapp_str8_lit_ro("WAPP"); Str8 expected = wapp_str8_lit_ro("WAPP");
U8Array bytes = wapp_array(u8, U8Array, 'W', 'A', 'P', 'P'); U8Array bytes = wapp_array(u8, 'W', 'A', 'P', 'P');
wapp_str8_from_bytes(&str, &bytes); wapp_str8_from_bytes(&str, bytes);
result = str.size == bytes.count * bytes.item_size; result = str.size == wapp_array_count(bytes) * wapp_array_item_size(bytes);
result = result && wapp_str8_equal(&str, &expected); result = result && wapp_str8_equal(&str, &expected);
return wapp_tester_result(result); return wapp_tester_result(result);

View File

@@ -10,33 +10,28 @@ TestFuncResult test_str8_list_get(void) {
Str8 s4 = wapp_str8_lit("4"); Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5"); Str8 s5 = wapp_str8_lit("5");
Str8List list = wapp_dbl_list(Str8, Str8List); Str8List list = wapp_dbl_list(Str8);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
wapp_dbl_list_push_back(Str8, &list, &n1); wapp_dbl_list_push_back(Str8, &list, &s1);
wapp_dbl_list_push_back(Str8, &list, &n2); wapp_dbl_list_push_back(Str8, &list, &s2);
wapp_dbl_list_push_back(Str8, &list, &n3); wapp_dbl_list_push_back(Str8, &list, &s3);
wapp_dbl_list_push_back(Str8, &list, &n4); wapp_dbl_list_push_back(Str8, &list, &s4);
wapp_dbl_list_push_back(Str8, &list, &n5); wapp_dbl_list_push_back(Str8, &list, &s5);
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, &list, 0); Str8 *node = wapp_dbl_list_get(Str8, &list, 0);
result = node->item == &s1 && wapp_str8_equal(node->item, &s1); result = node == &s1 && wapp_str8_equal(node, &s1);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 1); node = wapp_dbl_list_get(Str8, &list, 1);
result = result && node->item == &s2 && wapp_str8_equal(node->item, &s2); result = result && node == &s2 && wapp_str8_equal(node, &s2);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 2); node = wapp_dbl_list_get(Str8, &list, 2);
result = result && node->item == &s3 && wapp_str8_equal(node->item, &s3); result = result && node == &s3 && wapp_str8_equal(node, &s3);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 3); node = wapp_dbl_list_get(Str8, &list, 3);
result = result && node->item == &s4 && wapp_str8_equal(node->item, &s4); result = result && node == &s4 && wapp_str8_equal(node, &s4);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 4); node = wapp_dbl_list_get(Str8, &list, 4);
result = result && node->item == &s5 && wapp_str8_equal(node->item, &s5); result = result && node == &s5 && wapp_str8_equal(node, &s5);
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -48,19 +43,16 @@ TestFuncResult test_str8_list_push_front(void) {
Str8 s2 = wapp_str8_lit("2"); Str8 s2 = wapp_str8_lit("2");
Str8 s3 = wapp_str8_lit("3"); Str8 s3 = wapp_str8_lit("3");
Str8List list = wapp_dbl_list(Str8, Str8List); Str8List list = wapp_dbl_list(Str8);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
wapp_dbl_list_push_front(Str8, &list, &n1); wapp_dbl_list_push_front(Str8, &list, &s1);
result = list.first == list.last && list.first == &n1 && list.first->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1; result = list.first == list.last && list.first->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
wapp_dbl_list_push_front(Str8, &list, &n2); wapp_dbl_list_push_front(Str8, &list, &s2);
result = result && list.first == &n2 && list.first->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2; result = result && list.first->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
wapp_dbl_list_push_front(Str8, &list, &n3); wapp_dbl_list_push_front(Str8, &list, &s3);
result = result && list.first == &n3 && list.first->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3; result = result && list.first->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -72,19 +64,16 @@ TestFuncResult test_str8_list_push_back(void) {
Str8 s2 = wapp_str8_lit("2"); Str8 s2 = wapp_str8_lit("2");
Str8 s3 = wapp_str8_lit("3"); Str8 s3 = wapp_str8_lit("3");
Str8List list = wapp_dbl_list(Str8, Str8List); Str8List list = wapp_dbl_list(Str8);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
wapp_dbl_list_push_back(Str8, &list, &n1); wapp_dbl_list_push_back(Str8, &list, &s1);
result = list.first == list.last && list.last == &n1 && list.last->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1; result = list.first == list.last && list.last->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
wapp_dbl_list_push_back(Str8, &list, &n2); wapp_dbl_list_push_back(Str8, &list, &s2);
result = result && list.last == &n2 && list.last->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2; result = result && list.last->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
wapp_dbl_list_push_back(Str8, &list, &n3); wapp_dbl_list_push_back(Str8, &list, &s3);
result = result && list.last == &n3 && list.last->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3; result = result && list.last->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -100,28 +89,21 @@ TestFuncResult test_str8_list_insert(void) {
Str8 s6 = wapp_str8_lit("6"); Str8 s6 = wapp_str8_lit("6");
Str8 s7 = wapp_str8_lit("7"); Str8 s7 = wapp_str8_lit("7");
Str8List list = wapp_dbl_list(Str8, Str8List); Str8List list = wapp_dbl_list(Str8);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
Str8Node n6 = wapp_str8_node_from_str8(s6);
Str8Node n7 = wapp_str8_node_from_str8(s7);
wapp_dbl_list_push_back(Str8, &list, &n1); wapp_dbl_list_push_back(Str8, &list, &s1);
wapp_dbl_list_push_back(Str8, &list, &n2); wapp_dbl_list_push_back(Str8, &list, &s2);
wapp_dbl_list_push_back(Str8, &list, &n3); wapp_dbl_list_push_back(Str8, &list, &s3);
wapp_dbl_list_push_back(Str8, &list, &n4); wapp_dbl_list_push_back(Str8, &list, &s4);
wapp_dbl_list_push_back(Str8, &list, &n5); wapp_dbl_list_push_back(Str8, &list, &s5);
Str8Node *node; Str8 *node;
wapp_dbl_list_insert(Str8, &list, &n6, 2); wapp_dbl_list_insert(Str8, &list, &s6, 2);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 2); node = wapp_dbl_list_get(Str8, &list, 2);
result = node != NULL && node->item == &s6 && wapp_str8_list_total_size(&list) == 6 && list.node_count == 6; result = node != NULL && node == &s6 && wapp_str8_list_total_size(&list) == 6 && list.node_count == 6;
wapp_dbl_list_insert(Str8, &list, &n7, 5); wapp_dbl_list_insert(Str8, &list, &s7, 5);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 5); node = wapp_dbl_list_get(Str8, &list, 5);
result = result && node != NULL && node->item == &s7 && wapp_str8_list_total_size(&list) == 7 && list.node_count == 7; result = result && node != NULL && node == &s7 && wapp_str8_list_total_size(&list) == 7 && list.node_count == 7;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -135,33 +117,28 @@ TestFuncResult test_str8_list_pop_front(void) {
Str8 s4 = wapp_str8_lit("4"); Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5"); Str8 s5 = wapp_str8_lit("5");
Str8List list = wapp_dbl_list(Str8, Str8List); Str8List list = wapp_dbl_list(Str8);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
wapp_dbl_list_push_back(Str8, &list, &n1); wapp_dbl_list_push_back(Str8, &list, &s1);
wapp_dbl_list_push_back(Str8, &list, &n2); wapp_dbl_list_push_back(Str8, &list, &s2);
wapp_dbl_list_push_back(Str8, &list, &n3); wapp_dbl_list_push_back(Str8, &list, &s3);
wapp_dbl_list_push_back(Str8, &list, &n4); wapp_dbl_list_push_back(Str8, &list, &s4);
wapp_dbl_list_push_back(Str8, &list, &n5); wapp_dbl_list_push_back(Str8, &list, &s5);
Str8Node *node = wapp_dbl_list_pop_front(Str8, Str8Node, &list); Str8 *node = wapp_dbl_list_pop_front(Str8, &list);
result = node == &n1 && node->item == &s1 && wapp_str8_equal(node->item, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4; result = node == &s1 && wapp_str8_equal(node, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
node = wapp_dbl_list_pop_front(Str8, Str8Node, &list); node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &n2 && node->item == &s2 && wapp_str8_equal(node->item, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3; result = result && node == &s2 && wapp_str8_equal(node, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_pop_front(Str8, Str8Node, &list); node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &n3 && node->item == &s3 && wapp_str8_equal(node->item, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2; result = result && node == &s3 && wapp_str8_equal(node, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_pop_front(Str8, Str8Node, &list); node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &n4 && node->item == &s4 && wapp_str8_equal(node->item, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1; result = result && node == &s4 && wapp_str8_equal(node, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_pop_front(Str8, Str8Node, &list); node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &n5 && node->item == &s5 && wapp_str8_equal(node->item, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0; result = result && node == &s5 && wapp_str8_equal(node, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -175,33 +152,28 @@ TestFuncResult test_str8_list_pop_back(void) {
Str8 s4 = wapp_str8_lit("4"); Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5"); Str8 s5 = wapp_str8_lit("5");
Str8List list = wapp_dbl_list(Str8, Str8List); Str8List list = wapp_dbl_list(Str8);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
wapp_dbl_list_push_front(Str8, &list, &n1); wapp_dbl_list_push_front(Str8, &list, &s1);
wapp_dbl_list_push_front(Str8, &list, &n2); wapp_dbl_list_push_front(Str8, &list, &s2);
wapp_dbl_list_push_front(Str8, &list, &n3); wapp_dbl_list_push_front(Str8, &list, &s3);
wapp_dbl_list_push_front(Str8, &list, &n4); wapp_dbl_list_push_front(Str8, &list, &s4);
wapp_dbl_list_push_front(Str8, &list, &n5); wapp_dbl_list_push_front(Str8, &list, &s5);
Str8Node *node = wapp_dbl_list_pop_back(Str8, Str8Node, &list); Str8 *node = wapp_dbl_list_pop_back(Str8, &list);
result = node == &n1 && node->item == &s1 && wapp_str8_equal(node->item, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4; result = node == &s1 && wapp_str8_equal(node, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
node = wapp_dbl_list_pop_back(Str8, Str8Node, &list); node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &n2 && node->item == &s2 && wapp_str8_equal(node->item, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3; result = result && node == &s2 && wapp_str8_equal(node, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_pop_back(Str8, Str8Node, &list); node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &n3 && node->item == &s3 && wapp_str8_equal(node->item, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2; result = result && node == &s3 && wapp_str8_equal(node, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_pop_back(Str8, Str8Node, &list); node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &n4 && node->item == &s4 && wapp_str8_equal(node->item, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1; result = result && node == &s4 && wapp_str8_equal(node, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_pop_back(Str8, Str8Node, &list); node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &n5 && node->item == &s5 && wapp_str8_equal(node->item, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0; result = result && node == &s5 && wapp_str8_equal(node, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -215,33 +187,28 @@ TestFuncResult test_str8_list_remove(void) {
Str8 s4 = wapp_str8_lit("4"); Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5"); Str8 s5 = wapp_str8_lit("5");
Str8List list = wapp_dbl_list(Str8, Str8List); Str8List list = wapp_dbl_list(Str8);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
wapp_dbl_list_push_back(Str8, &list, &n1); wapp_dbl_list_push_back(Str8, &list, &s1);
wapp_dbl_list_push_back(Str8, &list, &n2); wapp_dbl_list_push_back(Str8, &list, &s2);
wapp_dbl_list_push_back(Str8, &list, &n3); wapp_dbl_list_push_back(Str8, &list, &s3);
wapp_dbl_list_push_back(Str8, &list, &n4); wapp_dbl_list_push_back(Str8, &list, &s4);
wapp_dbl_list_push_back(Str8, &list, &n5); wapp_dbl_list_push_back(Str8, &list, &s5);
Str8Node *node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0); Str8 *node = wapp_dbl_list_remove(Str8, &list, 0);
result = node == &n1 && node->item == &s1 && wapp_str8_equal(node->item, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4; result = node == &s1 && wapp_str8_equal(node, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0); node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &n2 && node->item == &s2 && wapp_str8_equal(node->item, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3; result = result && node == &s2 && wapp_str8_equal(node, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0); node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &n3 && node->item == &s3 && wapp_str8_equal(node->item, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2; result = result && node == &s3 && wapp_str8_equal(node, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0); node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &n4 && node->item == &s4 && wapp_str8_equal(node->item, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1; result = result && node == &s4 && wapp_str8_equal(node, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0); node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &n5 && node->item == &s5 && wapp_str8_equal(node->item, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0; result = result && node == &s5 && wapp_str8_equal(node, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -249,11 +216,11 @@ TestFuncResult test_str8_list_remove(void) {
TestFuncResult test_str8_list_empty(void) { TestFuncResult test_str8_list_empty(void) {
b8 result; b8 result;
Str8List list = wapp_dbl_list(Str8, Str8List); Str8List list = wapp_dbl_list(Str8);
wapp_dbl_list_push_back(Str8, &list, &wapp_str8_node_from_cstr("Hello")); wapp_dbl_list_push_back(Str8, &list, &wapp_str8_lit("Hello"));
wapp_dbl_list_push_back(Str8, &list, &wapp_str8_node_from_cstr("from")); wapp_dbl_list_push_back(Str8, &list, &wapp_str8_lit("from"));
wapp_dbl_list_push_back(Str8, &list, &wapp_str8_node_from_cstr("wizapp")); wapp_dbl_list_push_back(Str8, &list, &wapp_str8_lit("wizapp"));
wapp_dbl_list_push_back(Str8, &list, &wapp_str8_node_from_cstr("stdlib")); wapp_dbl_list_push_back(Str8, &list, &wapp_str8_lit("stdlib"));
wapp_dbl_list_empty(Str8, &list); wapp_dbl_list_empty(Str8, &list);

View File

@@ -10,33 +10,28 @@ TestFuncResult test_str8_list_get(void) {
Str8 s4 = wapp_str8_lit("4"); Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5"); Str8 s5 = wapp_str8_lit("5");
Str8List list = wapp_dbl_list(Str8, Str8List); Str8List list = wapp_dbl_list(Str8);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
wapp_dbl_list_push_back(Str8, &list, &n1); wapp_dbl_list_push_back(Str8, &list, &s1);
wapp_dbl_list_push_back(Str8, &list, &n2); wapp_dbl_list_push_back(Str8, &list, &s2);
wapp_dbl_list_push_back(Str8, &list, &n3); wapp_dbl_list_push_back(Str8, &list, &s3);
wapp_dbl_list_push_back(Str8, &list, &n4); wapp_dbl_list_push_back(Str8, &list, &s4);
wapp_dbl_list_push_back(Str8, &list, &n5); wapp_dbl_list_push_back(Str8, &list, &s5);
Str8Node *node = wapp_dbl_list_get(Str8, Str8Node, &list, 0); Str8 *node = wapp_dbl_list_get(Str8, &list, 0);
result = node->item == &s1 && wapp_str8_equal(node->item, &s1); result = node == &s1 && wapp_str8_equal(node, &s1);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 1); node = wapp_dbl_list_get(Str8, &list, 1);
result = result && node->item == &s2 && wapp_str8_equal(node->item, &s2); result = result && node == &s2 && wapp_str8_equal(node, &s2);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 2); node = wapp_dbl_list_get(Str8, &list, 2);
result = result && node->item == &s3 && wapp_str8_equal(node->item, &s3); result = result && node == &s3 && wapp_str8_equal(node, &s3);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 3); node = wapp_dbl_list_get(Str8, &list, 3);
result = result && node->item == &s4 && wapp_str8_equal(node->item, &s4); result = result && node == &s4 && wapp_str8_equal(node, &s4);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 4); node = wapp_dbl_list_get(Str8, &list, 4);
result = result && node->item == &s5 && wapp_str8_equal(node->item, &s5); result = result && node == &s5 && wapp_str8_equal(node, &s5);
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -48,19 +43,16 @@ TestFuncResult test_str8_list_push_front(void) {
Str8 s2 = wapp_str8_lit("2"); Str8 s2 = wapp_str8_lit("2");
Str8 s3 = wapp_str8_lit("3"); Str8 s3 = wapp_str8_lit("3");
Str8List list = wapp_dbl_list(Str8, Str8List); Str8List list = wapp_dbl_list(Str8);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
wapp_dbl_list_push_front(Str8, &list, &n1); wapp_dbl_list_push_front(Str8, &list, &s1);
result = list.first == list.last && list.first == &n1 && list.first->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1; result = list.first == list.last && list.first->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
wapp_dbl_list_push_front(Str8, &list, &n2); wapp_dbl_list_push_front(Str8, &list, &s2);
result = result && list.first == &n2 && list.first->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2; result = result && list.first->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
wapp_dbl_list_push_front(Str8, &list, &n3); wapp_dbl_list_push_front(Str8, &list, &s3);
result = result && list.first == &n3 && list.first->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3; result = result && list.first->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -72,19 +64,16 @@ TestFuncResult test_str8_list_push_back(void) {
Str8 s2 = wapp_str8_lit("2"); Str8 s2 = wapp_str8_lit("2");
Str8 s3 = wapp_str8_lit("3"); Str8 s3 = wapp_str8_lit("3");
Str8List list = wapp_dbl_list(Str8, Str8List); Str8List list = wapp_dbl_list(Str8);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
wapp_dbl_list_push_back(Str8, &list, &n1); wapp_dbl_list_push_back(Str8, &list, &s1);
result = list.first == list.last && list.last == &n1 && list.last->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1; result = list.first == list.last && list.last->item == &s1 && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
wapp_dbl_list_push_back(Str8, &list, &n2); wapp_dbl_list_push_back(Str8, &list, &s2);
result = result && list.last == &n2 && list.last->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2; result = result && list.last->item == &s2 && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
wapp_dbl_list_push_back(Str8, &list, &n3); wapp_dbl_list_push_back(Str8, &list, &s3);
result = result && list.last == &n3 && list.last->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3; result = result && list.last->item == &s3 && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -100,28 +89,21 @@ TestFuncResult test_str8_list_insert(void) {
Str8 s6 = wapp_str8_lit("6"); Str8 s6 = wapp_str8_lit("6");
Str8 s7 = wapp_str8_lit("7"); Str8 s7 = wapp_str8_lit("7");
Str8List list = wapp_dbl_list(Str8, Str8List); Str8List list = wapp_dbl_list(Str8);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
Str8Node n6 = wapp_str8_node_from_str8(s6);
Str8Node n7 = wapp_str8_node_from_str8(s7);
wapp_dbl_list_push_back(Str8, &list, &n1); wapp_dbl_list_push_back(Str8, &list, &s1);
wapp_dbl_list_push_back(Str8, &list, &n2); wapp_dbl_list_push_back(Str8, &list, &s2);
wapp_dbl_list_push_back(Str8, &list, &n3); wapp_dbl_list_push_back(Str8, &list, &s3);
wapp_dbl_list_push_back(Str8, &list, &n4); wapp_dbl_list_push_back(Str8, &list, &s4);
wapp_dbl_list_push_back(Str8, &list, &n5); wapp_dbl_list_push_back(Str8, &list, &s5);
Str8Node *node; Str8 *node;
wapp_dbl_list_insert(Str8, &list, &n6, 2); wapp_dbl_list_insert(Str8, &list, &s6, 2);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 2); node = wapp_dbl_list_get(Str8, &list, 2);
result = node != NULL && node->item == &s6 && wapp_str8_list_total_size(&list) == 6 && list.node_count == 6; result = node != NULL && node == &s6 && wapp_str8_list_total_size(&list) == 6 && list.node_count == 6;
wapp_dbl_list_insert(Str8, &list, &n7, 5); wapp_dbl_list_insert(Str8, &list, &s7, 5);
node = wapp_dbl_list_get(Str8, Str8Node, &list, 5); node = wapp_dbl_list_get(Str8, &list, 5);
result = result && node != NULL && node->item == &s7 && wapp_str8_list_total_size(&list) == 7 && list.node_count == 7; result = result && node != NULL && node == &s7 && wapp_str8_list_total_size(&list) == 7 && list.node_count == 7;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -135,33 +117,28 @@ TestFuncResult test_str8_list_pop_front(void) {
Str8 s4 = wapp_str8_lit("4"); Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5"); Str8 s5 = wapp_str8_lit("5");
Str8List list = wapp_dbl_list(Str8, Str8List); Str8List list = wapp_dbl_list(Str8);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
wapp_dbl_list_push_back(Str8, &list, &n1); wapp_dbl_list_push_back(Str8, &list, &s1);
wapp_dbl_list_push_back(Str8, &list, &n2); wapp_dbl_list_push_back(Str8, &list, &s2);
wapp_dbl_list_push_back(Str8, &list, &n3); wapp_dbl_list_push_back(Str8, &list, &s3);
wapp_dbl_list_push_back(Str8, &list, &n4); wapp_dbl_list_push_back(Str8, &list, &s4);
wapp_dbl_list_push_back(Str8, &list, &n5); wapp_dbl_list_push_back(Str8, &list, &s5);
Str8Node *node = wapp_dbl_list_pop_front(Str8, Str8Node, &list); Str8 *node = wapp_dbl_list_pop_front(Str8, &list);
result = node == &n1 && node->item == &s1 && wapp_str8_equal(node->item, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4; result = node == &s1 && wapp_str8_equal(node, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
node = wapp_dbl_list_pop_front(Str8, Str8Node, &list); node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &n2 && node->item == &s2 && wapp_str8_equal(node->item, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3; result = result && node == &s2 && wapp_str8_equal(node, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_pop_front(Str8, Str8Node, &list); node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &n3 && node->item == &s3 && wapp_str8_equal(node->item, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2; result = result && node == &s3 && wapp_str8_equal(node, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_pop_front(Str8, Str8Node, &list); node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &n4 && node->item == &s4 && wapp_str8_equal(node->item, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1; result = result && node == &s4 && wapp_str8_equal(node, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_pop_front(Str8, Str8Node, &list); node = wapp_dbl_list_pop_front(Str8, &list);
result = result && node == &n5 && node->item == &s5 && wapp_str8_equal(node->item, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0; result = result && node == &s5 && wapp_str8_equal(node, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -175,33 +152,28 @@ TestFuncResult test_str8_list_pop_back(void) {
Str8 s4 = wapp_str8_lit("4"); Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5"); Str8 s5 = wapp_str8_lit("5");
Str8List list = wapp_dbl_list(Str8, Str8List); Str8List list = wapp_dbl_list(Str8);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
wapp_dbl_list_push_front(Str8, &list, &n1); wapp_dbl_list_push_front(Str8, &list, &s1);
wapp_dbl_list_push_front(Str8, &list, &n2); wapp_dbl_list_push_front(Str8, &list, &s2);
wapp_dbl_list_push_front(Str8, &list, &n3); wapp_dbl_list_push_front(Str8, &list, &s3);
wapp_dbl_list_push_front(Str8, &list, &n4); wapp_dbl_list_push_front(Str8, &list, &s4);
wapp_dbl_list_push_front(Str8, &list, &n5); wapp_dbl_list_push_front(Str8, &list, &s5);
Str8Node *node = wapp_dbl_list_pop_back(Str8, Str8Node, &list); Str8 *node = wapp_dbl_list_pop_back(Str8, &list);
result = node == &n1 && node->item == &s1 && wapp_str8_equal(node->item, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4; result = node == &s1 && wapp_str8_equal(node, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
node = wapp_dbl_list_pop_back(Str8, Str8Node, &list); node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &n2 && node->item == &s2 && wapp_str8_equal(node->item, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3; result = result && node == &s2 && wapp_str8_equal(node, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_pop_back(Str8, Str8Node, &list); node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &n3 && node->item == &s3 && wapp_str8_equal(node->item, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2; result = result && node == &s3 && wapp_str8_equal(node, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_pop_back(Str8, Str8Node, &list); node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &n4 && node->item == &s4 && wapp_str8_equal(node->item, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1; result = result && node == &s4 && wapp_str8_equal(node, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_pop_back(Str8, Str8Node, &list); node = wapp_dbl_list_pop_back(Str8, &list);
result = result && node == &n5 && node->item == &s5 && wapp_str8_equal(node->item, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0; result = result && node == &s5 && wapp_str8_equal(node, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -215,33 +187,28 @@ TestFuncResult test_str8_list_remove(void) {
Str8 s4 = wapp_str8_lit("4"); Str8 s4 = wapp_str8_lit("4");
Str8 s5 = wapp_str8_lit("5"); Str8 s5 = wapp_str8_lit("5");
Str8List list = wapp_dbl_list(Str8, Str8List); Str8List list = wapp_dbl_list(Str8);
Str8Node n1 = wapp_str8_node_from_str8(s1);
Str8Node n2 = wapp_str8_node_from_str8(s2);
Str8Node n3 = wapp_str8_node_from_str8(s3);
Str8Node n4 = wapp_str8_node_from_str8(s4);
Str8Node n5 = wapp_str8_node_from_str8(s5);
wapp_dbl_list_push_back(Str8, &list, &n1); wapp_dbl_list_push_back(Str8, &list, &s1);
wapp_dbl_list_push_back(Str8, &list, &n2); wapp_dbl_list_push_back(Str8, &list, &s2);
wapp_dbl_list_push_back(Str8, &list, &n3); wapp_dbl_list_push_back(Str8, &list, &s3);
wapp_dbl_list_push_back(Str8, &list, &n4); wapp_dbl_list_push_back(Str8, &list, &s4);
wapp_dbl_list_push_back(Str8, &list, &n5); wapp_dbl_list_push_back(Str8, &list, &s5);
Str8Node *node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0); Str8 *node = wapp_dbl_list_remove(Str8, &list, 0);
result = node == &n1 && node->item == &s1 && wapp_str8_equal(node->item, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4; result = node == &s1 && wapp_str8_equal(node, &s1) && wapp_str8_list_total_size(&list) == 4 && list.node_count == 4;
node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0); node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &n2 && node->item == &s2 && wapp_str8_equal(node->item, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3; result = result && node == &s2 && wapp_str8_equal(node, &s2) && wapp_str8_list_total_size(&list) == 3 && list.node_count == 3;
node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0); node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &n3 && node->item == &s3 && wapp_str8_equal(node->item, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2; result = result && node == &s3 && wapp_str8_equal(node, &s3) && wapp_str8_list_total_size(&list) == 2 && list.node_count == 2;
node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0); node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &n4 && node->item == &s4 && wapp_str8_equal(node->item, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1; result = result && node == &s4 && wapp_str8_equal(node, &s4) && wapp_str8_list_total_size(&list) == 1 && list.node_count == 1;
node = wapp_dbl_list_remove(Str8, Str8Node, &list, 0); node = wapp_dbl_list_remove(Str8, &list, 0);
result = result && node == &n5 && node->item == &s5 && wapp_str8_equal(node->item, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0; result = result && node == &s5 && wapp_str8_equal(node, &s5) && wapp_str8_list_total_size(&list) == 0 && list.node_count == 0;
return wapp_tester_result(result); return wapp_tester_result(result);
} }
@@ -249,18 +216,18 @@ TestFuncResult test_str8_list_remove(void) {
TestFuncResult test_str8_list_empty(void) { TestFuncResult test_str8_list_empty(void) {
b8 result; b8 result;
Str8List list = wapp_dbl_list(Str8, Str8List); Str8List list = wapp_dbl_list(Str8);
Str8Node hello = wapp_str8_node_from_cstr("Hello"); Str8 hello = wapp_str8_lit("Hello");
wapp_dbl_list_push_back(Str8, &list, &hello); wapp_dbl_list_push_back(Str8, &list, &hello);
Str8Node from = wapp_str8_node_from_cstr("from"); Str8 from = wapp_str8_lit("from");
wapp_dbl_list_push_back(Str8, &list, &from); wapp_dbl_list_push_back(Str8, &list, &from);
Str8Node wizapp = wapp_str8_node_from_cstr("wizapp"); Str8 wizapp = wapp_str8_lit("wizapp");
wapp_dbl_list_push_back(Str8, &list, &wizapp); wapp_dbl_list_push_back(Str8, &list, &wizapp);
Str8Node stdlib = wapp_str8_node_from_cstr("stdlib"); Str8 stdlib = wapp_str8_lit("stdlib");
wapp_dbl_list_push_back(Str8, &list, &stdlib); wapp_dbl_list_push_back(Str8, &list, &stdlib);
wapp_dbl_list_empty(Str8, &list); wapp_dbl_list_empty(Str8, &list);

View File

@@ -4,7 +4,9 @@
#include "test_arena.h" #include "test_arena.h"
#include "test_str8_array.h" #include "test_str8_array.h"
#include "test_i32_array.h" #include "test_i32_array.h"
#include "test_queue.h"
#include "test_cpath.h" #include "test_cpath.h"
#include "test_file.h"
#include "test_shell_commander.h" #include "test_shell_commander.h"
#include "wapp.h" #include "wapp.h"
#include <stdlib.h> #include <stdlib.h>
@@ -12,14 +14,22 @@
int main(void) { int main(void) {
wapp_tester_run_tests( wapp_tester_run_tests(
test_arena_allocator, test_arena_allocator,
test_arena_init, test_arena_allocator_with_buffer,
test_arena_allocator_temp_begin,
test_arena_allocator_temp_end,
test_arena_init_buffer,
test_arena_init_allocated,
test_arena_init_succeeds_when_reserving_very_large_size, test_arena_init_succeeds_when_reserving_very_large_size,
test_arena_alloc_with_buffer,
test_arena_alloc_succeeds_when_within_capacity, test_arena_alloc_succeeds_when_within_capacity,
test_arena_alloc_fails_when_over_capacity, test_arena_alloc_fails_when_over_capacity,
test_arena_realloc_bigger_size, test_arena_realloc_bigger_size,
test_arena_realloc_smaller_size, test_arena_realloc_smaller_size,
test_arena_temp_begin,
test_arena_temp_end,
test_arena_clear, test_arena_clear,
test_arena_destroy, test_arena_destroy_buffer,
test_arena_destroy_allocated,
test_str8_array, test_str8_array,
test_i32_array, test_i32_array,
test_i32_array_with_capacity, test_i32_array_with_capacity,
@@ -34,6 +44,9 @@ int main(void) {
test_i32_array_copy_alloc, test_i32_array_copy_alloc,
test_i32_array_pop, test_i32_array_pop,
test_i32_array_clear, test_i32_array_clear,
test_queue_push,
test_queue_push_alloc,
test_queue_pop,
test_str8_lit, test_str8_lit,
test_str8_lit_ro, test_str8_lit_ro,
test_str8_buf, test_str8_buf,
@@ -70,6 +83,18 @@ int main(void) {
test_cpath_join_path, test_cpath_join_path,
test_cpath_dirname, test_cpath_dirname,
test_cpath_dirup, test_cpath_dirup,
test_wapp_file_open,
test_wapp_file_get_current_position,
test_wapp_file_seek,
test_wapp_file_get_length,
test_wapp_file_read,
test_wapp_file_write,
test_wapp_file_read_array,
test_wapp_file_write_array,
test_wapp_file_flush,
test_wapp_file_close,
test_wapp_file_rename,
test_wapp_file_remove,
test_commander_cmd_success, test_commander_cmd_success,
test_commander_cmd_failure, test_commander_cmd_failure,
test_commander_cmd_out_buf_success, test_commander_cmd_out_buf_success,

View File

@@ -4,7 +4,9 @@
#include "test_arena.h" #include "test_arena.h"
#include "test_str8_array.h" #include "test_str8_array.h"
#include "test_i32_array.h" #include "test_i32_array.h"
#include "test_queue.h"
#include "test_cpath.h" #include "test_cpath.h"
#include "test_file.h"
#include "test_shell_commander.h" #include "test_shell_commander.h"
#include "wapp.h" #include "wapp.h"
#include <stdlib.h> #include <stdlib.h>
@@ -12,14 +14,22 @@
int main(void) { int main(void) {
wapp_tester_run_tests( wapp_tester_run_tests(
test_arena_allocator, test_arena_allocator,
test_arena_init, test_arena_allocator_with_buffer,
test_arena_allocator_temp_begin,
test_arena_allocator_temp_end,
test_arena_init_buffer,
test_arena_init_allocated,
test_arena_init_succeeds_when_reserving_very_large_size, test_arena_init_succeeds_when_reserving_very_large_size,
test_arena_alloc_with_buffer,
test_arena_alloc_succeeds_when_within_capacity, test_arena_alloc_succeeds_when_within_capacity,
test_arena_alloc_fails_when_over_capacity, test_arena_alloc_fails_when_over_capacity,
test_arena_realloc_bigger_size, test_arena_realloc_bigger_size,
test_arena_realloc_smaller_size, test_arena_realloc_smaller_size,
test_arena_temp_begin,
test_arena_temp_end,
test_arena_clear, test_arena_clear,
test_arena_destroy, test_arena_destroy_buffer,
test_arena_destroy_allocated,
test_str8_array, test_str8_array,
test_i32_array, test_i32_array,
test_i32_array_with_capacity, test_i32_array_with_capacity,
@@ -27,13 +37,16 @@ int main(void) {
test_i32_array_set, test_i32_array_set,
test_i32_array_append_capped, test_i32_array_append_capped,
test_i32_array_extend_capped, test_i32_array_extend_capped,
test_i32_array_clear,
test_i32_array_pop,
test_i32_array_copy_capped, test_i32_array_copy_capped,
test_i32_array_alloc_capacity, test_i32_array_alloc_capacity,
test_i32_array_append_alloc, test_i32_array_append_alloc,
test_i32_array_extend_alloc, test_i32_array_extend_alloc,
test_i32_array_copy_alloc, test_i32_array_copy_alloc,
test_i32_array_pop,
test_i32_array_clear,
test_queue_push,
test_queue_push_alloc,
test_queue_pop,
test_str8_lit, test_str8_lit,
test_str8_lit_ro, test_str8_lit_ro,
test_str8_buf, test_str8_buf,
@@ -70,6 +83,18 @@ int main(void) {
test_cpath_join_path, test_cpath_join_path,
test_cpath_dirname, test_cpath_dirname,
test_cpath_dirup, test_cpath_dirup,
test_wapp_file_open,
test_wapp_file_get_current_position,
test_wapp_file_seek,
test_wapp_file_get_length,
test_wapp_file_read,
test_wapp_file_write,
test_wapp_file_read_array,
test_wapp_file_write_array,
test_wapp_file_flush,
test_wapp_file_close,
test_wapp_file_rename,
test_wapp_file_remove,
test_commander_cmd_success, test_commander_cmd_success,
test_commander_cmd_failure, test_commander_cmd_failure,
test_commander_cmd_out_buf_success, test_commander_cmd_out_buf_success,