Reorganize code, fix malloc bug, allow overriding defaults

This commit is contained in:
doyle 2020-04-15 00:40:12 +10:00
parent 32fd82d740
commit 21104f85d5
4 changed files with 1607 additions and 1543 deletions

File diff suppressed because it is too large Load Diff

View File

@ -64,10 +64,10 @@
#define DQN_IMPLEMENTATION
#include "Dqn.h"
char const *ParseFunctionReturnType(char const *ptr, isize *len)
char const *ParseFunctionReturnType(char const *ptr, Dqn_isize *len)
{
char const *result = Dqn_Str_SkipWhitespace(ptr);
isize result_len = 0;
Dqn_isize result_len = 0;
for (int scope = 0; ptr; ptr++) // NOTE: Parse the function return type
{
if (ptr[0] == '<' || ptr[0] == '>')
@ -88,7 +88,7 @@ char const *ParseFunctionReturnType(char const *ptr, isize *len)
return result;
}
char const *ParseFunctionNameAndParameters(char const *ptr, isize *len)
char const *ParseFunctionNameAndParameters(char const *ptr, Dqn_isize *len)
{
char const *result = ptr;
int result_len = 0;
@ -107,13 +107,13 @@ char const *ParseFunctionNameAndParameters(char const *ptr, isize *len)
return result;
}
char const *ParseFunctionComment(char const *ptr, isize *len)
char const *ParseFunctionComment(char const *ptr, Dqn_isize *len)
{
while (ptr[0] != '"') ptr++;
ptr++;
char const *result = ptr;
isize result_len = 0;
Dqn_isize result_len = 0;
for (;;)
{
while (ptr[0] != '"')
@ -167,10 +167,10 @@ int main(int argc, char *argv[])
arena.allocator = Dqn_Allocator_XHeap();
Dqn_Allocator allocator = Dqn_Allocator_Arena(&arena);
Dqn_MemArena_Reserve(&arena, DQN_MEGABYTES(16));
for (isize arg_index = 1; arg_index < argc; ++arg_index)
for (Dqn_isize arg_index = 1; arg_index < argc; ++arg_index)
{
char const *file = argv[arg_index];
isize buf_size = 0;
Dqn_isize buf_size = 0;
char *buf = Dqn_File_ReadAll(&allocator, file, &buf_size);
if (!buf)
{
@ -184,18 +184,18 @@ int main(int argc, char *argv[])
char constexpr HEADER_COPY_END[] = "DQN_HEADER_COPY_END";
char const *find_list[] = {HEADER_COPY_PROTOTYPE, HEADER_COMMENT, HEADER_COPY_BEGIN};
isize constexpr find_string_lens[] = {
Dqn_isize constexpr find_string_lens[] = {
Dqn_CharCountI(HEADER_COPY_PROTOTYPE),
Dqn_CharCountI(HEADER_COMMENT),
Dqn_CharCountI(HEADER_COPY_BEGIN),
};
isize num_header_entries = 0;
Dqn_isize num_header_entries = 0;
{
char const *ptr = buf;
char const *ptr_end = buf + buf_size;
isize ptr_len = buf_size;
isize matched_find_index = -1;
Dqn_isize ptr_len = buf_size;
Dqn_isize matched_find_index = -1;
for (char const *token = Dqn_Str_FindMulti(ptr, find_list, find_string_lens, Dqn_ArrayCountI(find_list), &matched_find_index, ptr_len);
token;
token = Dqn_Str_FindMulti(ptr, find_list, find_string_lens, Dqn_ArrayCountI(find_list), &matched_find_index, ptr_len))
@ -207,28 +207,28 @@ int main(int argc, char *argv[])
}
auto *header_entries = Dqn_MemArena_AllocateType<HeaderEntry>(&arena, num_header_entries);
isize header_entries_index = 0;
isize max_prototype_return_val = 0;
Dqn_isize header_entries_index = 0;
Dqn_isize max_prototype_return_val = 0;
char const *ptr = buf;
char const *ptr_end = buf + buf_size;
isize ptr_len = buf_size;
isize matched_find_index = -1;
Dqn_isize ptr_len = buf_size;
Dqn_isize matched_find_index = -1;
for (char const *token = Dqn_Str_FindMulti(ptr, find_list, find_string_lens, Dqn_ArrayCountI(find_list), &matched_find_index, ptr_len);
token;
token = Dqn_Str_FindMulti(ptr, find_list, find_string_lens, Dqn_ArrayCountI(find_list), &matched_find_index, ptr_len))
{
HeaderEntry *entry = header_entries + header_entries_index++;
entry->type = static_cast<HeaderEntryType>(matched_find_index);
if (matched_find_index == (isize)HeaderEntryType::Prototype)
if (matched_find_index == (Dqn_isize)HeaderEntryType::Prototype)
{
ptr = token + find_string_lens[matched_find_index] + 1 /*macro start parenthesis*/;
isize func_type_len = 0;
Dqn_isize func_type_len = 0;
char const *func_type = ParseFunctionReturnType(ptr, &func_type_len);
ptr = func_type + func_type_len + 1; // Ptr is at macro comma, skip the comma
ptr = Dqn_Str_SkipWhitespace(ptr);
isize func_name_len = 0;
Dqn_isize func_name_len = 0;
char const *func_name = ParseFunctionNameAndParameters(ptr, &func_name_len);
entry->function_decl.return_val = Dqn_Asprintf(&allocator, "%.*s", func_type_len, func_type);
@ -237,13 +237,13 @@ int main(int argc, char *argv[])
max_prototype_return_val = DQN_MAX(max_prototype_return_val, func_type_len);
}
else if (matched_find_index == (isize)HeaderEntryType::Comment)
else if (matched_find_index == (Dqn_isize)HeaderEntryType::Comment)
{
char const *comment_start = token;
ptr = token;
while (ptr[0] != '\n' && ptr[0] != '\r')
ptr++;
isize comment_len = ptr - comment_start;
Dqn_isize comment_len = ptr - comment_start;
entry->comment.str = Dqn_MemArena_AllocateType<char>(&arena, comment_len);
DQN_FOR_EACH(comment_index, comment_len)
@ -260,7 +260,7 @@ int main(int argc, char *argv[])
entry->comment.len--;
ptr = comment_start + comment_len;
}
else if (matched_find_index == (isize)HeaderEntryType::CopyBegin)
else if (matched_find_index == (Dqn_isize)HeaderEntryType::CopyBegin)
{
ptr = token + find_string_lens[matched_find_index];
ptr = Dqn_Str_SkipWhitespace(ptr);
@ -272,7 +272,7 @@ int main(int argc, char *argv[])
return -1;
}
isize copy_len = copy_end - copy_start;
Dqn_isize copy_len = copy_end - copy_start;
entry->copy_range.str = Dqn_MemArena_AllocateType<char>(&arena, copy_len);
DQN_FOR_EACH(copy_index, copy_len)
{
@ -294,7 +294,7 @@ int main(int argc, char *argv[])
{
case HeaderEntryType::Prototype:
{
isize remaining_space = max_prototype_return_val - entry->function_decl.return_val.len + 1;
Dqn_isize remaining_space = max_prototype_return_val - entry->function_decl.return_val.len + 1;
fprintf(stdout, "%.*s", (int)entry->function_decl.return_val.len, entry->function_decl.return_val.str);
DQN_FOR_EACH(space, remaining_space) fputs(" ", stdout);
fprintf(stdout, " %.*s;\n", (int)entry->function_decl.name_and_args.len, entry->function_decl.name_and_args.str);

View File

@ -202,14 +202,19 @@ template <typename T> T * Dqn_MemZero(T *src);
//
// -------------------------------------------------------------------------------------------------
// Custom allocations must include Dqn_AllocateMetadata before the aligned_ptr, see Dqn_AllocateMetadata for more information
// NOTE: The default allocator is the heap allocator
enum struct Dqn_Allocator_Type
{
#if defined(DQN_ALLOCATOR_DEFAULT_TO_NULL)
Null,
Heap, // Malloc, realloc, free
#else
Heap, // Malloc, realloc, free
Null,
#endif
XHeap, // Malloc realloc, free, crash on failure
Arena,
Custom,
Null,
};
#define DQN_ALLOCATOR_ALLOCATE_PROC(name) void *name(Dqn_isize size, Dqn_u8 alignment)
@ -227,11 +232,11 @@ struct Dqn_Allocator
struct Dqn_MemArena *arena;
} context;
isize bytes_allocated;
isize total_bytes_allocated;
Dqn_isize bytes_allocated;
Dqn_isize total_bytes_allocated;
isize allocations;
isize total_allocations;
Dqn_isize allocations;
Dqn_isize total_allocations;
// NOTE: Only required if type == Dqn_Allocator_Type::Custom
Dqn_Allocator_AllocateProc *allocate;
@ -239,7 +244,11 @@ struct Dqn_Allocator
Dqn_Allocator_FreeProc *free;
};
Dqn_Allocator inline Dqn_Allocator_Null();
Dqn_Allocator inline Dqn_Allocator_Heap();
Dqn_Allocator inline Dqn_Allocator_XHeap();
Dqn_Allocator inline Dqn_Allocator_Arena(Dqn_MemArena *arena);
template <typename T> T * Dqn_Allocator_AllocateType(Dqn_Allocator *allocator, Dqn_isize num);
// -------------------------------------------------------------------------------------------------
//
// NOTE: Dqn_AllocatorMetadata
@ -260,37 +269,43 @@ struct Dqn_AllocateMetadata
struct Dqn_MemBlock
{
void *memory;
Dqn_usize size;
Dqn_usize used;
Dqn_isize size;
Dqn_isize used;
Dqn_MemBlock *prev;
Dqn_MemBlock *next;
};
Dqn_usize const DQN_MEM_ARENA_DEFAULT_MIN_BLOCK_SIZE = DQN_KILOBYTES(4);
struct Dqn_MemArena
{
// NOTE: Configuration (fill once after "Zero Initialisation {}")
int min_block_size = DQN_KILOBYTES(4);
Dqn_isize min_block_size;
Dqn_Allocator allocator;
// NOTE: Read Only
Dqn_MemBlock *curr_mem_block;
Dqn_MemBlock *top_mem_block;
Dqn_usize highest_used_mark;
Dqn_isize highest_used_mark;
int total_allocated_mem_blocks;
};
struct Dqn_MemArenaRegion
{
Dqn_MemArena *arena;
Dqn_MemBlock *curr_mem_block;
Dqn_isize curr_mem_block_used;
Dqn_MemBlock *top_mem_block;
};
struct Dqn_MemArenaScopedRegion
{
Dqn_MemArenaScopedRegion(Dqn_MemArena *arena);
~Dqn_MemArenaScopedRegion();
Dqn_MemArena *arena;
Dqn_MemBlock *curr_mem_block;
Dqn_usize curr_mem_block_used;
Dqn_MemBlock *top_mem_block;
Dqn_MemArenaRegion region;
};
void * Dqn_MemArena_Allocate(Dqn_MemArena *arena, Dqn_usize size, Dqn_u8 alignment);
Dqn_b32 Dqn_MemArena_Reserve(Dqn_MemArena *arena, Dqn_usize size);
void * Dqn_MemArena_Allocate(Dqn_MemArena *arena, Dqn_isize size, Dqn_u8 alignment);
Dqn_b32 Dqn_MemArena_Reserve(Dqn_MemArena *arena, Dqn_isize size);
DQN_HEADER_COPY_PROTOTYPE(template <typename T> T *, Dqn_MemArena_AllocateType(Dqn_MemArena *arena, Dqn_isize num))
{
auto *result = DQN_CAST(T *)Dqn_MemArena_Allocate(arena, sizeof(T) * num, alignof(T));
@ -298,16 +313,6 @@ DQN_HEADER_COPY_PROTOTYPE(template <typename T> T *, Dqn_MemArena_AllocateType(D
}
// -------------------------------------------------------------------------------------------------
//
// NOTE: Dqn_Allocator
//
// -------------------------------------------------------------------------------------------------
Dqn_Allocator inline Dqn_Allocator_Null();
Dqn_Allocator inline Dqn_Allocator_Heap();
Dqn_Allocator inline Dqn_Allocator_XHeap();
Dqn_Allocator inline Dqn_Allocator_Arena(Dqn_MemArena *arena);
template <typename T> T * Dqn_Allocator_AllocateType(Dqn_Allocator *allocator, Dqn_isize num);
// -------------------------------------------------------------------------------------------------
//
// NOTE: String
@ -338,18 +343,18 @@ struct Dqn_String
struct Dqn_StringBuilderBuffer
{
char *mem;
Dqn_usize size;
Dqn_usize used;
Dqn_isize size;
Dqn_isize used;
Dqn_StringBuilderBuffer *next;
};
Dqn_usize constexpr DQN_STRING_BUILDER_MIN_MEM_BUF_ALLOC_SIZE = DQN_KILOBYTES(4);
Dqn_isize constexpr DQN_STRING_BUILDER_MIN_MEM_BUF_ALLOC_SIZE = DQN_KILOBYTES(4);
template <Dqn_usize N = DQN_KILOBYTES(16)>
struct Dqn_StringBuilder
{
Dqn_Allocator allocator;
char fixed_mem[N];
Dqn_usize fixed_mem_used;
Dqn_isize fixed_mem_used;
Dqn_StringBuilderBuffer *next_mem_buf;
Dqn_StringBuilderBuffer *last_mem_buf;
Dqn_isize string_len;
@ -388,6 +393,7 @@ template <typename T> inline bool Dqn_Slice_Equals(Dqn_Slice<T> const a,
DQN_FIXED_ARRAY_TEMPLATE struct Dqn_FixedArray
{
T data[MAX_];
Dqn_isize max = MAX_;
Dqn_isize len;
T &operator[] (Dqn_isize i) { DQN_ASSERT_MSG(i >= 0 && i <= len, "%jd >= 0 && %jd < %jd", i, len); return data[i]; }
@ -522,6 +528,7 @@ Dqn_b32 Dqn_Log(Dqn_LogType type, char const *
//
// -------------------------------------------------------------------------------------------------
char * Dqn_AllocateMetadata_Init(void *ptr, Dqn_u8 alignment);
// TODO(doyle): Use bit masks and only support POT. That approach reflects how computers work better.
Dqn_AllocateMetadata Dqn_AllocateMetadata_Get(void *ptr);
char * Dqn_AllocateMetadata_GetRawPointer(void *ptr);
Dqn_isize Dqn_AllocateMetadata_SizeRequired(Dqn_isize size, Dqn_u8 alignment);
@ -538,18 +545,18 @@ void Dqn_Allocator_Free(Dqn_Allocator *allo
// NOTE: Dqn_MemArena
//
// -------------------------------------------------------------------------------------------------
void * Dqn_MemArena_Allocate(Dqn_MemArena *arena, Dqn_usize size, u8 alignment);
void * Dqn_MemArena_Allocate(Dqn_MemArena *arena, Dqn_isize size, Dqn_u8 alignment);
void Dqn_MemArena_Free(Dqn_MemArena *arena);
Dqn_b32 Dqn_MemArena_Reserve(Dqn_MemArena *arena, Dqn_usize size);
Dqn_MemArena Dqn_MemArena_InitWithAllocator(Dqn_Allocator allocator, Dqn_usize size);
Dqn_MemArena Dqn_MemArena_InitMemory(void *memory, Dqn_usize size);
Dqn_b32 Dqn_MemArena_Reserve(Dqn_MemArena *arena, Dqn_isize size);
Dqn_MemArena Dqn_MemArena_InitWithAllocator(Dqn_Allocator allocator, Dqn_isize size);
Dqn_MemArena Dqn_MemArena_InitMemory(void *memory, Dqn_isize size);
void Dqn_MemArena_ResetUsage(Dqn_MemArena *arena, Dqn_ZeroMem zero_mem);
Dqn_MemArenaScopedRegion Dqn_MemArena_MakeScopedRegion(Dqn_MemArena *arena);
// -------------------------------------------------------------------------------------------------
//
// NOTE: Dqn_Asprintf (Allocate Sprintf)
//
// -------------------------------------------------------------------------------------------------
// return: The allocated string. If allocation fails, the str ptr returned is nullptr and length is set o the size required, NOT INCLUDING the null terminator.
Dqn_String Dqn_Asprintf(Dqn_Allocator *allocator, char const *fmt, va_list va);
Dqn_String Dqn_Asprintf(Dqn_Allocator *allocator, char const *fmt, ...);
// -------------------------------------------------------------------------------------------------
@ -586,7 +593,7 @@ Dqn_V2I Dqn_RectI32_Size(Dqn_RectI32 rect);
//
// -------------------------------------------------------------------------------------------------
Dqn_V2 Dqn_LerpV2(Dqn_V2 a, Dqn_f32 t, Dqn_V2 b);
f32 Dqn_LerpF32(f32 a, f32 t, f32 b);
Dqn_f32 Dqn_LerpF32(Dqn_f32 a, Dqn_f32 t, Dqn_f32 b);
// -------------------------------------------------------------------------------------------------
//
// NOTE: Dqn_Mat4
@ -616,6 +623,8 @@ Dqn_b32 Dqn_Bit_IsNotSet(Dqn_u32 flags, Dqn_u3
Dqn_i64 Dqn_Safe_AddI64(Dqn_i64 a, Dqn_i64 b);
Dqn_i64 Dqn_Safe_MulI64(Dqn_i64 a, Dqn_i64 b);
Dqn_u64 Dqn_Safe_AddU64(Dqn_u64 a, Dqn_u64 b);
Dqn_u64 Dqn_Safe_SubU64(Dqn_u64 a, Dqn_u64 b);
Dqn_u32 Dqn_Safe_SubU32(Dqn_u32 a, Dqn_u32 b);
Dqn_u64 Dqn_Safe_MulU64(Dqn_u64 a, Dqn_u64 b);
int Dqn_Safe_TruncateISizeToInt(Dqn_isize val);
Dqn_i32 Dqn_Safe_TruncateISizeToI32(Dqn_isize val);

View File

@ -69,7 +69,7 @@ void TestingState_PrintGroupResult(TestingState const *result)
bool all_tests_passed = (result->num_tests_ok_in_group == result->num_tests_in_group);
char buf[256] = {};
int len = snprintf(buf, Dqn_ArrayCount(buf), "%02d/%02d Tests Passed ", result->num_tests_ok_in_group, result->num_tests_in_group);
isize remaining_len = DESIRED_LEN - len - 1;
Dqn_isize remaining_len = DESIRED_LEN - len - 1;
remaining_len = (all_tests_passed) ? remaining_len - Dqn_CharCount(STATUS_OK) : remaining_len - Dqn_CharCount(STATUS_FAIL);
remaining_len = DQN_MAX(remaining_len, 0);
DQN_FOR_EACH(i, remaining_len) fprintf(stdout, " ");
@ -90,7 +90,7 @@ void TestState_PrintResult(TestState const *result)
char const STATUS_OK[] = "OK";
char const STATUS_FAIL[] = "FAIL";
isize remaining_len = DESIRED_LEN - result->name.len - Dqn_CharCount(INDENT);
Dqn_isize remaining_len = DESIRED_LEN - result->name.len - Dqn_CharCount(INDENT);
remaining_len = (result->fail_expr.str) ? remaining_len - Dqn_CharCount(STATUS_FAIL) : remaining_len - Dqn_CharCount(STATUS_OK);
remaining_len = DQN_MAX(remaining_len, 0);
@ -106,7 +106,7 @@ void TestState_PrintResult(TestState const *result)
}
}
FILE_SCOPE void UnitTests()
DQN_FILE_SCOPE void UnitTests()
{
TestingState testing_state = {};
// ---------------------------------------------------------------------------------------------
@ -142,6 +142,7 @@ FILE_SCOPE void UnitTests()
{
TEST_START_SCOPE(testing_state, "ArenaAllocator - Allocate Small");
Dqn_MemArena arena = {};
arena.allocator = Dqn_Allocator_Heap();
Dqn_Allocator allocator = Dqn_Allocator_Arena(&arena);
char constexpr EXPECT[] = "hello_world";
char *buf = DQN_CAST(char *)Dqn_Allocator_Allocate(&allocator, Dqn_ArrayCount(EXPECT), alignof(char));
@ -228,12 +229,12 @@ FILE_SCOPE void UnitTests()
// ---------------------------------------------------------------------------------------------
{
TEST_DECLARE_GROUP_SCOPED(testing_state, "Dqn_Array");
// NOTE: Dqn_Array_InitMemory
// NOTE: Dqn_Array_InitWithMemory
{
{
TEST_START_SCOPE(testing_state, "Fixed Memory: Test add single item and can't allocate more");
int memory[4] = {};
Dqn_Array<int> array = Dqn_Array_InitMemory(memory, Dqn_ArrayCount(memory), 0 /*len*/);
Dqn_Array<int> array = Dqn_Array_InitWithMemory(memory, Dqn_ArrayCount(memory), 0 /*len*/);
Dqn_Array_Add(&array, 1);
Dqn_Array_Add(&array, 2);
Dqn_Array_Add(&array, 3);
@ -254,7 +255,7 @@ FILE_SCOPE void UnitTests()
TEST_START_SCOPE(testing_state, "Fixed Memory: Test add array of items");
int memory[4] = {};
int DATA[] = {1, 2, 3};
Dqn_Array<int> array = Dqn_Array_InitMemory(memory, Dqn_ArrayCount(memory), 0 /*len*/);
Dqn_Array<int> array = Dqn_Array_InitWithMemory(memory, Dqn_ArrayCount(memory), 0 /*len*/);
Dqn_Array_Add(&array, DATA, Dqn_ArrayCount(DATA));
TEST_EXPECT_MSG(testing_state, array.data[0] == 1, "array.data %d", array.data[0]);
TEST_EXPECT_MSG(testing_state, array.data[1] == 2, "array.data %d", array.data[1]);
@ -267,7 +268,7 @@ FILE_SCOPE void UnitTests()
TEST_START_SCOPE(testing_state, "Fixed Memory: Test clear and clear with memory zeroed");
int memory[4] = {};
int DATA[] = {1, 2, 3};
Dqn_Array<int> array = Dqn_Array_InitMemory(memory, Dqn_ArrayCount(memory), 0 /*len*/);
Dqn_Array<int> array = Dqn_Array_InitWithMemory(memory, Dqn_ArrayCount(memory), 0 /*len*/);
Dqn_Array_Add(&array, DATA, Dqn_ArrayCount(DATA));
Dqn_Array_Clear(&array, false /*zero_mem*/);
TEST_EXPECT_MSG(testing_state, array.len == 0, "array.len: %d", array.len);
@ -282,7 +283,7 @@ FILE_SCOPE void UnitTests()
TEST_START_SCOPE(testing_state, "Fixed Memory: Test erase stable and erase unstable");
int memory[4] = {};
int DATA[] = {1, 2, 3, 4};
Dqn_Array<int> array = Dqn_Array_InitMemory(memory, Dqn_ArrayCount(memory), 0 /*len*/);
Dqn_Array<int> array = Dqn_Array_InitWithMemory(memory, Dqn_ArrayCount(memory), 0 /*len*/);
Dqn_Array_Add(&array, DATA, Dqn_ArrayCount(DATA));
Dqn_Array_EraseUnstable(&array, 1);
TEST_EXPECT_MSG(testing_state, array.data[0] == 1, "array.data %d", array.data[0]);
@ -300,7 +301,7 @@ FILE_SCOPE void UnitTests()
TEST_START_SCOPE(testing_state, "Fixed Memory: Test array pop and peek");
int memory[4] = {};
int DATA[] = {1, 2, 3};
Dqn_Array<int> array = Dqn_Array_InitMemory(memory, Dqn_ArrayCount(memory), 0 /*len*/);
Dqn_Array<int> array = Dqn_Array_InitWithMemory(memory, Dqn_ArrayCount(memory), 0 /*len*/);
Dqn_Array_Add(&array, DATA, Dqn_ArrayCount(DATA));
Dqn_Array_Pop(&array, 2);
TEST_EXPECT_MSG(testing_state, array.data[0] == 1, "array.data: %d", array.data[0]);
@ -316,7 +317,7 @@ FILE_SCOPE void UnitTests()
{
TEST_START_SCOPE(testing_state, "Fixed Memory: Test free on fixed memory array does nothing");
int memory[4] = {};
Dqn_Array<int> array = Dqn_Array_InitMemory(memory, Dqn_ArrayCount(memory), 0 /*len*/);
Dqn_Array<int> array = Dqn_Array_InitWithMemory(memory, Dqn_ArrayCount(memory), 0 /*len*/);
DQN_DEFER { Dqn_Array_Free(&array); };
}
}
@ -496,7 +497,7 @@ FILE_SCOPE void UnitTests()
Dqn_StringBuilder<> builder = {};
Dqn_StringBuilder_Append(&builder, "Abc", 1);
Dqn_StringBuilder_Append(&builder, "cd");
isize len = 0;
Dqn_isize len = 0;
char *result = Dqn_StringBuilder_Build(&builder, &allocator, &len);
DQN_DEFER { Dqn_Allocator_Free(&allocator, result); };
@ -510,7 +511,7 @@ FILE_SCOPE void UnitTests()
Dqn_StringBuilder<> builder = {};
Dqn_StringBuilder_Append(&builder, "");
Dqn_StringBuilder_Append(&builder, "");
isize len = 0;
Dqn_isize len = 0;
char *result = Dqn_StringBuilder_Build(&builder, &allocator, &len);
DQN_DEFER { Dqn_Allocator_Free(&allocator, result); };
@ -524,7 +525,7 @@ FILE_SCOPE void UnitTests()
Dqn_StringBuilder<> builder = {};
Dqn_StringBuilder_Append(&builder, "Acd");
Dqn_StringBuilder_Append(&builder, "");
isize len = 0;
Dqn_isize len = 0;
char *result = Dqn_StringBuilder_Build(&builder, &allocator, &len);
DQN_DEFER { Dqn_Allocator_Free(&allocator, result); };
@ -537,7 +538,7 @@ FILE_SCOPE void UnitTests()
TEST_START_SCOPE(testing_state, "Append nullptr and build using heap allocator");
Dqn_StringBuilder<> builder = {};
Dqn_StringBuilder_Append(&builder, nullptr, 5);
isize len = 0;
Dqn_isize len = 0;
char *result = Dqn_StringBuilder_Build(&builder, &allocator, &len);
DQN_DEFER { Dqn_Allocator_Free(&allocator, result); };
@ -552,7 +553,7 @@ FILE_SCOPE void UnitTests()
Dqn_StringBuilder_Append(&builder, "A");
Dqn_StringBuilder_Append(&builder, "z"); // Should force a new memory block
Dqn_StringBuilder_Append(&builder, "tec");
isize len = 0;
Dqn_isize len = 0;
char *result = Dqn_StringBuilder_Build(&builder, &allocator, &len);
DQN_DEFER { Dqn_Allocator_Free(&allocator, result); };
@ -568,7 +569,7 @@ FILE_SCOPE void UnitTests()
Dqn_StringBuilder<> builder = {};
Dqn_StringBuilder_AppendChar(&builder, 'a');
Dqn_StringBuilder_AppendChar(&builder, 'b');
isize len = 0;
Dqn_isize len = 0;
char *result = Dqn_StringBuilder_Build(&builder, &allocator, &len);
DQN_DEFER { Dqn_Allocator_Free(&allocator, result); };
@ -584,7 +585,7 @@ FILE_SCOPE void UnitTests()
Dqn_StringBuilder<> builder = {};
Dqn_StringBuilder_FmtAppend(&builder, "Number: %d, String: %s, ", 4, "Hello Sailor");
Dqn_StringBuilder_FmtAppend(&builder, "Extra Stuff");
isize len = 0;
Dqn_isize len = 0;
char *result = Dqn_StringBuilder_Build(&builder, &allocator, &len);
DQN_DEFER { Dqn_Allocator_Free(&allocator, result); };
@ -597,7 +598,7 @@ FILE_SCOPE void UnitTests()
TEST_START_SCOPE(testing_state, "Append nullptr format string and build using heap allocator");
Dqn_StringBuilder<> builder = {};
Dqn_StringBuilder_FmtAppend(&builder, nullptr);
isize len = 0;
Dqn_isize len = 0;
char *result = Dqn_StringBuilder_Build(&builder, &allocator, &len);
DQN_DEFER { Dqn_Allocator_Free(&allocator, result); };
@ -701,55 +702,55 @@ FILE_SCOPE void UnitTests()
TEST_DECLARE_GROUP_SCOPED(testing_state, "Dqn_Str_ToI64");
{
TEST_START_SCOPE(testing_state, "Convert nullptr");
i64 result = Dqn_Str_ToI64(nullptr);
Dqn_i64 result = Dqn_Str_ToI64(nullptr);
TEST_EXPECT(testing_state, result == 0);
}
{
TEST_START_SCOPE(testing_state, "Convert empty string");
i64 result = Dqn_Str_ToI64("");
Dqn_i64 result = Dqn_Str_ToI64("");
TEST_EXPECT(testing_state, result == 0);
}
{
TEST_START_SCOPE(testing_state, "Convert \"1\"");
i64 result = Dqn_Str_ToI64("1");
Dqn_i64 result = Dqn_Str_ToI64("1");
TEST_EXPECT(testing_state, result == 1);
}
{
TEST_START_SCOPE(testing_state, "Convert \"-0\"");
i64 result = Dqn_Str_ToI64("-0");
Dqn_i64 result = Dqn_Str_ToI64("-0");
TEST_EXPECT(testing_state, result == 0);
}
{
TEST_START_SCOPE(testing_state, "Convert \"-1\"");
i64 result = Dqn_Str_ToI64("-1");
Dqn_i64 result = Dqn_Str_ToI64("-1");
TEST_EXPECT(testing_state, result == -1);
}
{
TEST_START_SCOPE(testing_state, "Convert \"1.2\"");
i64 result = Dqn_Str_ToI64("1.2");
Dqn_i64 result = Dqn_Str_ToI64("1.2");
TEST_EXPECT(testing_state, result == 1);
}
{
TEST_START_SCOPE(testing_state, "Convert \"1,234\"");
i64 result = Dqn_Str_ToI64("1,234");
Dqn_i64 result = Dqn_Str_ToI64("1,234");
TEST_EXPECT(testing_state, result == 1234);
}
{
TEST_START_SCOPE(testing_state, "Convert \"1,2\"");
i64 result = Dqn_Str_ToI64("1,2");
Dqn_i64 result = Dqn_Str_ToI64("1,2");
TEST_EXPECT(testing_state, result == 12);
}
{
TEST_START_SCOPE(testing_state, "Convert \"12a3\"");
i64 result = Dqn_Str_ToI64("12a3");
Dqn_i64 result = Dqn_Str_ToI64("12a3");
TEST_EXPECT(testing_state, result == 12);
}
}
@ -763,55 +764,55 @@ FILE_SCOPE void UnitTests()
TEST_DECLARE_GROUP_SCOPED(testing_state, "Dqn_Str_ToU64");
{
TEST_START_SCOPE(testing_state, "Convert nullptr");
u64 result = Dqn_Str_ToU64(nullptr);
Dqn_u64 result = Dqn_Str_ToU64(nullptr);
TEST_EXPECT(testing_state, result == 0);
}
{
TEST_START_SCOPE(testing_state, "Convert empty string");
u64 result = Dqn_Str_ToU64("");
Dqn_u64 result = Dqn_Str_ToU64("");
TEST_EXPECT(testing_state, result == 0);
}
{
TEST_START_SCOPE(testing_state, "Convert \"1\"");
u64 result = Dqn_Str_ToU64("1");
Dqn_u64 result = Dqn_Str_ToU64("1");
TEST_EXPECT(testing_state, result == 1);
}
{
TEST_START_SCOPE(testing_state, "Convert \"-0\"");
u64 result = Dqn_Str_ToU64("-0");
Dqn_u64 result = Dqn_Str_ToU64("-0");
TEST_EXPECT(testing_state, result == 0);
}
{
TEST_START_SCOPE(testing_state, "Convert \"-1\"");
u64 result = Dqn_Str_ToU64("-1");
Dqn_u64 result = Dqn_Str_ToU64("-1");
TEST_EXPECT(testing_state, result == 0);
}
{
TEST_START_SCOPE(testing_state, "Convert \"1.2\"");
u64 result = Dqn_Str_ToU64("1.2");
Dqn_u64 result = Dqn_Str_ToU64("1.2");
TEST_EXPECT(testing_state, result == 1);
}
{
TEST_START_SCOPE(testing_state, "Convert \"1,234\"");
u64 result = Dqn_Str_ToU64("1,234");
Dqn_u64 result = Dqn_Str_ToU64("1,234");
TEST_EXPECT(testing_state, result == 1234);
}
{
TEST_START_SCOPE(testing_state, "Convert \"1,2\"");
u64 result = Dqn_Str_ToU64("1,2");
Dqn_u64 result = Dqn_Str_ToU64("1,2");
TEST_EXPECT(testing_state, result == 12);
}
{
TEST_START_SCOPE(testing_state, "Convert \"12a3\"");
u64 result = Dqn_Str_ToU64("12a3");
Dqn_u64 result = Dqn_Str_ToU64("12a3");
TEST_EXPECT(testing_state, result == 12);
}
}