Get latest changes from upstream
This commit is contained in:
+1104
-450
File diff suppressed because it is too large
Load Diff
+703
-510
File diff suppressed because it is too large
Load Diff
+731
-248
File diff suppressed because it is too large
Load Diff
+875
-60
File diff suppressed because it is too large
Load Diff
@@ -1,77 +0,0 @@
|
|||||||
#if !defined(DN_BASE_ASSERT_H)
|
|
||||||
#define DN_BASE_ASSERT_H
|
|
||||||
|
|
||||||
#define DN_HardAssertF(expr, fmt, ...) \
|
|
||||||
do { \
|
|
||||||
if (!(expr)) { \
|
|
||||||
DN_Str8 stack_trace_ = DN_StackTraceWalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \
|
|
||||||
DN_LogErrorF("Hard assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \
|
|
||||||
DN_Str8PrintFmt(stack_trace_), \
|
|
||||||
##__VA_ARGS__); \
|
|
||||||
DN_DebugBreak; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
#define DN_HardAssert(expr) DN_HardAssertF(expr, "")
|
|
||||||
|
|
||||||
// NOTE: Our default assert requires stack traces which has a bit of a chicken-and-egg problem if
|
|
||||||
// we're trying to detect some code related to the DN startup sequence. If we try to assert before
|
|
||||||
// the OS layer is initialised stack-traces will try to use temporary memory which requires TLS to
|
|
||||||
// be setup which belongs to the OS.
|
|
||||||
//
|
|
||||||
// This causes recursion errors as they call into each other. We use RawAsserts for these kind of
|
|
||||||
// checks.
|
|
||||||
#if defined(DN_NO_ASSERT)
|
|
||||||
#define DN_RawAssert(...)
|
|
||||||
#define DN_Assert(...)
|
|
||||||
#define DN_AssertOnce(...)
|
|
||||||
#define DN_AssertF(...)
|
|
||||||
#define DN_AssertFOnce(...)
|
|
||||||
#else
|
|
||||||
#define DN_RawAssert(expr) do { if (!(expr)) DN_DebugBreak; } while (0)
|
|
||||||
|
|
||||||
#define DN_AssertF(expr, fmt, ...) \
|
|
||||||
do { \
|
|
||||||
if (!(expr)) { \
|
|
||||||
DN_Str8 stack_trace_ = DN_StackTraceWalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \
|
|
||||||
DN_LogErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \
|
|
||||||
DN_Str8PrintFmt(stack_trace_), \
|
|
||||||
##__VA_ARGS__); \
|
|
||||||
DN_DebugBreak; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define DN_AssertFOnce(expr, fmt, ...) \
|
|
||||||
do { \
|
|
||||||
static bool once = true; \
|
|
||||||
if (!(expr) && once) { \
|
|
||||||
once = false; \
|
|
||||||
DN_Str8 stack_trace_ = DN_StackTraceWalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \
|
|
||||||
DN_LogErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \
|
|
||||||
DN_Str8PrintFmt(stack_trace_), \
|
|
||||||
##__VA_ARGS__); \
|
|
||||||
DN_DebugBreak; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define DN_Assert(expr) DN_AssertF((expr), "")
|
|
||||||
#define DN_AssertOnce(expr) DN_AssertFOnce((expr), "")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DN_InvalidCodePathF(fmt, ...) DN_HardAssertF(0, fmt, ##__VA_ARGS__)
|
|
||||||
#define DN_InvalidCodePath DN_InvalidCodePathF("Invalid code path triggered")
|
|
||||||
#define DN_StaticAssert(expr) \
|
|
||||||
DN_GCC_WARNING_PUSH \
|
|
||||||
DN_GCC_WARNING_DISABLE(-Wunused-local-typedefs) \
|
|
||||||
typedef char DN_TokenCombine(static_assert_dummy__, __LINE__)[(expr) ? 1 : -1]; \
|
|
||||||
DN_GCC_WARNING_POP
|
|
||||||
|
|
||||||
#define DN_Check(expr) DN_CheckF(expr, "")
|
|
||||||
#if defined(DN_NO_CHECK_BREAK)
|
|
||||||
#define DN_CheckF(expr, fmt, ...) \
|
|
||||||
((expr) ? true : (DN_LogWarningF(fmt, ##__VA_ARGS__), false))
|
|
||||||
#else
|
|
||||||
#define DN_CheckF(expr, fmt, ...) \
|
|
||||||
((expr) ? true : (DN_LogErrorF(fmt, ##__VA_ARGS__), DN_StackTracePrint(128 /*limit*/), DN_DebugBreak, false))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -2,6 +2,13 @@
|
|||||||
#include "../dn.h"
|
#include "../dn.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct DN_ArrayFindEqMemcmpContext_
|
||||||
|
{
|
||||||
|
DN_USize elem_size;
|
||||||
|
void const *find;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
DN_API void *DN_SliceAllocArena(void **data, DN_USize *slice_size_field, DN_USize size, DN_USize elem_size, DN_U8 align, DN_ZMem zmem, DN_Arena *arena)
|
DN_API void *DN_SliceAllocArena(void **data, DN_USize *slice_size_field, DN_USize size, DN_USize elem_size, DN_U8 align, DN_ZMem zmem, DN_Arena *arena)
|
||||||
{
|
{
|
||||||
void *result = *data;
|
void *result = *data;
|
||||||
@@ -11,7 +18,42 @@ DN_API void *DN_SliceAllocArena(void **data, DN_USize *slice_size_field, DN_USiz
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API void *DN_CArrayInsertArray(void *data, DN_USize *size, DN_USize max, DN_USize elem_size, DN_USize index, void const *items, DN_USize count)
|
DN_API DN_ArrayFindResult DN_ArrayFind(void *data, DN_USize size, DN_USize elem_size, void const *find, DN_ArrayFindEqFunc *eq_func)
|
||||||
|
{
|
||||||
|
DN_ArrayFindResult result = {};
|
||||||
|
DN_Assert(data);
|
||||||
|
DN_Assert(elem_size);
|
||||||
|
if (find) {
|
||||||
|
for (DN_ForIndexU(index, size)) {
|
||||||
|
DN_U8 *it = DN_Cast(DN_U8 *) data + (index * elem_size);
|
||||||
|
if (eq_func(it, find)) {
|
||||||
|
result.index = index;
|
||||||
|
result.value = it;
|
||||||
|
result.success = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool DN_ArrayFindEqMemEqUnsafe_(void const *lhs, void const *find)
|
||||||
|
{
|
||||||
|
DN_ArrayFindEqMemcmpContext_ *context = DN_Cast(DN_ArrayFindEqMemcmpContext_ *) find;
|
||||||
|
bool result = DN_MemEqUnsafe(lhs, context->find, context->elem_size);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API DN_ArrayFindResult DN_ArrayFindMemEq(void *data, DN_USize size, DN_USize elem_size, void const *find)
|
||||||
|
{
|
||||||
|
DN_ArrayFindEqMemcmpContext_ context = {};
|
||||||
|
context.elem_size = elem_size;
|
||||||
|
context.find = find;
|
||||||
|
DN_ArrayFindResult result = DN_ArrayFind(data, size, elem_size, &context, DN_ArrayFindEqMemEqUnsafe_);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API void *DN_ArrayInsertArray(void *data, DN_USize *size, DN_USize max, DN_USize elem_size, DN_USize index, void const *items, DN_USize count)
|
||||||
{
|
{
|
||||||
void *result = nullptr;
|
void *result = nullptr;
|
||||||
if (!data || !size || !items || count <= 0 || ((*size + count) > max))
|
if (!data || !size || !items || count <= 0 || ((*size + count) > max))
|
||||||
@@ -32,7 +74,7 @@ DN_API void *DN_CArrayInsertArray(void *data, DN_USize *size, DN_USize max, DN_U
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API void *DN_CArrayPopFront(void *data, DN_USize *size, DN_USize elem_size, DN_USize count)
|
DN_API void *DN_ArrayPopFront(void *data, DN_USize *size, DN_USize elem_size, DN_USize count)
|
||||||
{
|
{
|
||||||
if (!data || !size || *size == 0 || count == 0)
|
if (!data || !size || *size == 0 || count == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -51,7 +93,7 @@ DN_API void *DN_CArrayPopFront(void *data, DN_USize *size, DN_USize elem_size, D
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API void *DN_CArrayPopBack(void *data, DN_USize *size, DN_USize elem_size, DN_USize count)
|
DN_API void *DN_ArrayPopBack(void *data, DN_USize *size, DN_USize elem_size, DN_USize count)
|
||||||
{
|
{
|
||||||
if (!data || !size || *size == 0 || count == 0)
|
if (!data || !size || *size == 0 || count == 0)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -62,7 +104,7 @@ DN_API void *DN_CArrayPopBack(void *data, DN_USize *size, DN_USize elem_size, DN
|
|||||||
return DN_Cast(char *)data + (*size * elem_size);
|
return DN_Cast(char *)data + (*size * elem_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API DN_ArrayEraseResult DN_CArrayEraseRange(void *data, DN_USize *size, DN_USize elem_size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase)
|
DN_API DN_ArrayEraseResult DN_ArrayEraseRange(void *data, DN_USize *size, DN_USize elem_size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase)
|
||||||
{
|
{
|
||||||
DN_ArrayEraseResult result = {};
|
DN_ArrayEraseResult result = {};
|
||||||
if (!data || !size || *size == 0 || count == 0)
|
if (!data || !size || *size == 0 || count == 0)
|
||||||
@@ -104,48 +146,47 @@ DN_API DN_ArrayEraseResult DN_CArrayEraseRange(void *data, DN_USize *size, DN_US
|
|||||||
}
|
}
|
||||||
|
|
||||||
result.items_erased = erase_count;
|
result.items_erased = erase_count;
|
||||||
result.it_index = start;
|
result.it_index = start ? start - 1 : start;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API void *DN_CArrayMakeArray(void *data, DN_USize *size, DN_USize max, DN_USize data_size, DN_USize make_size, DN_ZMem z_mem)
|
DN_API void *DN_ArrayMakeArray(void *data, DN_USize *size, DN_USize max, DN_USize elem_size, DN_USize make_count, DN_ZMem z_mem)
|
||||||
{
|
{
|
||||||
void *result = nullptr;
|
void *result = nullptr;
|
||||||
DN_USize new_size = *size + make_size;
|
DN_USize new_size = *size + make_count;
|
||||||
if (new_size <= max) {
|
if (new_size <= max) {
|
||||||
result = DN_Cast(char *) data + (data_size * size[0]);
|
result = DN_Cast(char *) data + (elem_size * size[0]);
|
||||||
*size = new_size;
|
*size = new_size;
|
||||||
if (z_mem == DN_ZMem_Yes)
|
if (z_mem == DN_ZMem_Yes)
|
||||||
DN_Memset(result, 0, data_size * make_size);
|
DN_Memset(result, 0, elem_size * make_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API void *DN_CArrayAddArray(void *data, DN_USize *size, DN_USize max, DN_USize data_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add)
|
DN_API void *DN_ArrayAddArray(void *data, DN_USize *size, DN_USize max, DN_USize elem_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add)
|
||||||
{
|
{
|
||||||
void *result = DN_CArrayMakeArray(data, size, max, data_size, elems_count, DN_ZMem_No);
|
void *result = DN_ArrayMakeArray(data, size, max, elem_size, elems_count, DN_ZMem_No);
|
||||||
if (result) {
|
if (result) {
|
||||||
if (add == DN_ArrayAdd_Append) {
|
if (add == DN_ArrayAdd_Append) {
|
||||||
DN_Memcpy(result, elems, elems_count * data_size);
|
DN_Memcpy(result, elems, elems_count * elem_size);
|
||||||
} else {
|
} else {
|
||||||
char *move_dest = DN_Cast(char *)data + (elems_count * data_size); // Shift elements forward
|
char *move_dest = DN_Cast(char *)data + (elems_count * elem_size); // Shift elements forward
|
||||||
char *move_src = DN_Cast(char *)data;
|
char *move_src = DN_Cast(char *)data;
|
||||||
DN_Memmove(move_dest, move_src, data_size * size[0]);
|
DN_Memmove(move_dest, move_src, elem_size * size[0]);
|
||||||
DN_Memcpy(data, elems, data_size * elems_count);
|
DN_Memcpy(data, elems, elem_size * elems_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API bool DN_CArrayResizeFromArena(void **data, DN_USize *size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize new_max)
|
DN_API bool DN_ArrayResizeFromArena(void **data, DN_USize *size, DN_USize *max, DN_USize elem_size, DN_Pool *pool, DN_USize new_max)
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
if (new_max != *max) {
|
if (new_max != *max) {
|
||||||
DN_USize bytes_to_alloc = data_size * new_max;
|
DN_USize bytes_to_alloc = elem_size * new_max;
|
||||||
void *buffer = DN_PoolNewArray(pool, DN_U8, bytes_to_alloc);
|
void *buffer = DN_PoolNewArray(pool, DN_U8, bytes_to_alloc);
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
DN_USize bytes_to_copy = data_size * DN_Min(*size, new_max);
|
DN_USize bytes_to_copy = elem_size * DN_Min(*size, new_max);
|
||||||
DN_Memcpy(buffer, *data, bytes_to_copy);
|
DN_Memcpy(buffer, *data, bytes_to_copy);
|
||||||
DN_PoolDealloc(pool, *data);
|
DN_PoolDealloc(pool, *data);
|
||||||
*data = buffer;
|
*data = buffer;
|
||||||
@@ -159,14 +200,14 @@ DN_API bool DN_CArrayResizeFromArena(void **data, DN_USize *size, DN_USize *max,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API bool DN_CArrayResizeFromPool(void **data, DN_USize *size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize new_max)
|
DN_API bool DN_ArrayResizeFromPool(void **data, DN_USize *size, DN_USize *max, DN_USize elem_size, DN_Pool *pool, DN_USize new_max)
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
if (new_max != *max) {
|
if (new_max != *max) {
|
||||||
DN_USize bytes_to_alloc = data_size * new_max;
|
DN_USize bytes_to_alloc = elem_size * new_max;
|
||||||
void *buffer = DN_PoolNewArray(pool, DN_U8, bytes_to_alloc);
|
void *buffer = DN_PoolNewArray(pool, DN_U8, bytes_to_alloc);
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
DN_USize bytes_to_copy = data_size * DN_Min(*size, new_max);
|
DN_USize bytes_to_copy = elem_size * DN_Min(*size, new_max);
|
||||||
DN_Memcpy(buffer, *data, bytes_to_copy);
|
DN_Memcpy(buffer, *data, bytes_to_copy);
|
||||||
DN_PoolDealloc(pool, *data);
|
DN_PoolDealloc(pool, *data);
|
||||||
*data = buffer;
|
*data = buffer;
|
||||||
@@ -180,14 +221,14 @@ DN_API bool DN_CArrayResizeFromPool(void **data, DN_USize *size, DN_USize *max,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API bool DN_CArrayResizeFromArena(void **data, DN_USize *size, DN_USize *max, DN_USize data_size, DN_Arena *arena, DN_USize new_max)
|
DN_API bool DN_ArrayResizeFromArena(void **data, DN_USize *size, DN_USize *max, DN_USize elem_size, DN_Arena *arena, DN_USize new_max)
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
if (new_max != *max) {
|
if (new_max != *max) {
|
||||||
DN_USize bytes_to_alloc = data_size * new_max;
|
DN_USize bytes_to_alloc = elem_size * new_max;
|
||||||
void *buffer = DN_ArenaNewArray(arena, DN_U8, bytes_to_alloc, DN_ZMem_No);
|
void *buffer = DN_ArenaNewArray(arena, DN_U8, bytes_to_alloc, DN_ZMem_No);
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
DN_USize bytes_to_copy = data_size * DN_Min(*size, new_max);
|
DN_USize bytes_to_copy = elem_size * DN_Min(*size, new_max);
|
||||||
DN_Memcpy(buffer, *data, bytes_to_copy);
|
DN_Memcpy(buffer, *data, bytes_to_copy);
|
||||||
*data = buffer;
|
*data = buffer;
|
||||||
*max = new_max;
|
*max = new_max;
|
||||||
@@ -200,41 +241,41 @@ DN_API bool DN_CArrayResizeFromArena(void **data, DN_USize *size, DN_USize *max,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API bool DN_CArrayGrowFromPool(void **data, DN_USize size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize new_max)
|
DN_API bool DN_ArrayGrowFromPool(void **data, DN_USize size, DN_USize *max, DN_USize elem_size, DN_Pool *pool, DN_USize new_max)
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
if (new_max > *max)
|
if (new_max > *max)
|
||||||
result = DN_CArrayResizeFromPool(data, &size, max, data_size, pool, new_max);
|
result = DN_ArrayResizeFromPool(data, &size, max, elem_size, pool, new_max);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API bool DN_CArrayGrowFromArena(void **data, DN_USize size, DN_USize *max, DN_USize data_size, DN_Arena *arena, DN_USize new_max)
|
DN_API bool DN_ArrayGrowFromArena(void **data, DN_USize size, DN_USize *max, DN_USize elem_size, DN_Arena *arena, DN_USize new_max)
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
if (new_max > *max)
|
if (new_max > *max)
|
||||||
result = DN_CArrayResizeFromArena(data, &size, max, data_size, arena, new_max);
|
result = DN_ArrayResizeFromArena(data, &size, max, elem_size, arena, new_max);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DN_API bool DN_CArrayGrowIfNeededFromPool(void **data, DN_USize size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize add_count)
|
DN_API bool DN_ArrayGrowIfNeededFromPool(void **data, DN_USize size, DN_USize *max, DN_USize elem_size, DN_Pool *pool, DN_USize add_count)
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
DN_USize new_size = size + add_count;
|
DN_USize new_size = size + add_count;
|
||||||
if (new_size > *max) {
|
if (new_size > *max) {
|
||||||
DN_USize new_max = DN_Max(DN_Max(*max * 2, new_size), 8);
|
DN_USize new_max = DN_Max(DN_Max(*max * 2, new_size), 8);
|
||||||
result = DN_CArrayResizeFromPool(data, &size, max, data_size, pool, new_max);
|
result = DN_ArrayResizeFromPool(data, &size, max, elem_size, pool, new_max);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API bool DN_CArrayGrowIfNeededFromArena(void **data, DN_USize size, DN_USize *max, DN_USize data_size, DN_Arena *arena, DN_USize add_count)
|
DN_API bool DN_ArrayGrowIfNeededFromArena(void **data, DN_USize size, DN_USize *max, DN_USize elem_size, DN_Arena *arena, DN_USize add_count)
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
DN_USize new_size = size + add_count;
|
DN_USize new_size = size + add_count;
|
||||||
if (new_size > *max) {
|
if (new_size > *max) {
|
||||||
DN_USize new_max = DN_Max(DN_Max(*max * 2, new_size), 8);
|
DN_USize new_max = DN_Max(DN_Max(*max * 2, new_size), 8);
|
||||||
result = DN_CArrayResizeFromArena(data, &size, max, data_size, arena, new_max);
|
result = DN_ArrayResizeFromArena(data, &size, max, elem_size, arena, new_max);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,463 +0,0 @@
|
|||||||
#if !defined(DN_CONTAINERS_H)
|
|
||||||
#define DN_CONTAINERS_H
|
|
||||||
// Containers that are imlpemented using primarily macros for operating on data structures that are
|
|
||||||
// embedded into a C style struct or from a set of defined variables from the available scope. Keep
|
|
||||||
// it stupid simple, structs and functions. Minimal amount of container types with flexible
|
|
||||||
// construction leads to less duplicated container code and less template meta-programming.
|
|
||||||
//
|
|
||||||
// Arrays
|
|
||||||
//
|
|
||||||
// Data structures that have a `T *data`, `DN_USize count` and `DN_USize max` capacity that can be
|
|
||||||
// dynamically shrunk or expanded.
|
|
||||||
//
|
|
||||||
// API
|
|
||||||
// ResizeFrom: Resizes the array to `new_max` erase elements if resizing to a smaller size
|
|
||||||
// GrowFrom: Expands the capacity of the array if `new_max > array.max` otherwise no-op
|
|
||||||
// GrowIfNeeded: Expands the capacity of the array if `array.size + add_count > array.max` otherwise no-op
|
|
||||||
//
|
|
||||||
// Variants
|
|
||||||
// PArray => Pointer (to) Array
|
|
||||||
// LArray => Literal Array
|
|
||||||
// Define a C array and size. (P) array macros take a pointer to the aray, its size and its max
|
|
||||||
// capacity. The (L) array macros take the literal array and derives the max capacity
|
|
||||||
// automatically using DN_ArrayCountU(l_array).
|
|
||||||
//
|
|
||||||
// MyStruct buffer[TB_ASType_Count] = {};
|
|
||||||
// DN_USize size = 0;
|
|
||||||
// MyStruct *item_0 = DN_PArrayMake(buffer, &size, DN_ArrayCountU(buffer), DN_ZMem_No);
|
|
||||||
// MyStruct *item_1 = DN_LArrayMake(buffer, &size, DN_ZMem_No);
|
|
||||||
//
|
|
||||||
// IArray => Intrusive Array
|
|
||||||
// Define a struct with the members `data`, `size` and `max`:
|
|
||||||
//
|
|
||||||
// struct MyArray {
|
|
||||||
// MyStruct *data;
|
|
||||||
// DN_USize size;
|
|
||||||
// DN_USize max;
|
|
||||||
// } my_array = {};
|
|
||||||
// DN_Arena arena = {};
|
|
||||||
// DN_IArrayResizeFromArena(&my_array, &arena, 256);
|
|
||||||
// MyStruct *item = DN_IArrayMake(&my_array, DN_ZMem_No);
|
|
||||||
//
|
|
||||||
// Slices
|
|
||||||
//
|
|
||||||
// Fixed size container allocated up front that have a `T *data` and `DN_USize count` elements.
|
|
||||||
//
|
|
||||||
// API
|
|
||||||
// AllocArena: Allocates the container with the requested `count` elements
|
|
||||||
//
|
|
||||||
// ISinglyLL => Intrusive Singly Linked List
|
|
||||||
// Define a struct with the members `next`:
|
|
||||||
//
|
|
||||||
// struct MyLinkItem {
|
|
||||||
// int data;
|
|
||||||
// MyLinkItem *next;
|
|
||||||
// } my_link = {};
|
|
||||||
//
|
|
||||||
// MyLinkItem *first_item = DN_ISinglyLLDetach(&my_link, MyLinkItem);
|
|
||||||
//
|
|
||||||
// DoublyLL => Doubly Linked List
|
|
||||||
// Define a struct with the members `next` and `prev`. This list has null pointers for head->prev
|
|
||||||
// and tail->next.
|
|
||||||
//
|
|
||||||
// struct MyLinkItem {
|
|
||||||
// int data;
|
|
||||||
// MyLinkItem *next;
|
|
||||||
// MyLinkItem *prev;
|
|
||||||
// } my_link = {};
|
|
||||||
//
|
|
||||||
// MyLinkItem first_item = {}, second_item = {};
|
|
||||||
// DN_DoublyLLAppend(&first_item, &second_item); // first_item -> second_item
|
|
||||||
//
|
|
||||||
// SentinelDoublyLL => Sentinel Doubly Linked List
|
|
||||||
// Uses a sentinel/dummy node as the list head. The sentinel points to itself when empty.
|
|
||||||
// Define a struct with the members `next` and `prev`:
|
|
||||||
//
|
|
||||||
// struct MyLinkItem {
|
|
||||||
// int data;
|
|
||||||
// MyLinkItem *next;
|
|
||||||
// MyLinkItem *prev;
|
|
||||||
// } my_list = {};
|
|
||||||
//
|
|
||||||
// DN_SentinelDoublyLLInit(&my_list);
|
|
||||||
// DN_SentinelDoublyLLAppend(&my_list, &new_item);
|
|
||||||
// DN_SentinelDoublyLLForEach(it, &my_list) { /* ... */ }
|
|
||||||
//
|
|
||||||
// SinglyHeadTailLL => Singly Linked List with Head and Tail pointer (or First and Last pointer)
|
|
||||||
/*
|
|
||||||
struct MyLinkItem {
|
|
||||||
int data;
|
|
||||||
MyLinkItem *next;
|
|
||||||
} my_list = {};
|
|
||||||
|
|
||||||
struct MyContainer {
|
|
||||||
MyLinkItem *head;
|
|
||||||
MyLinkItem *tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
MyLinkItem item = {};
|
|
||||||
MyContainer container = {};
|
|
||||||
DN_ISinglyHeadTailLLAppend(container, item);
|
|
||||||
// ... or alternatively, DN_SinglyHeadTailLLAppend(container.head, container.tail, item);
|
|
||||||
|
|
||||||
for (MyLinkItem *it = container.head; it; it = it->next) { }
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(_CLANGD)
|
|
||||||
#include "../dn.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct DN_Ring
|
|
||||||
{
|
|
||||||
DN_U64 size;
|
|
||||||
char *base;
|
|
||||||
DN_U64 write_pos;
|
|
||||||
DN_U64 read_pos;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DN_ArrayErase
|
|
||||||
{
|
|
||||||
DN_ArrayErase_Unstable,
|
|
||||||
DN_ArrayErase_Stable,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DN_ArrayAdd
|
|
||||||
{
|
|
||||||
DN_ArrayAdd_Append,
|
|
||||||
DN_ArrayAdd_Prepend,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DN_ArrayEraseResult
|
|
||||||
{
|
|
||||||
// The next index your for-index should be set to such that you can continue
|
|
||||||
// to iterate the remainder of the array, e.g:
|
|
||||||
//
|
|
||||||
// for (DN_USize index = 0; index < array.size; index++) {
|
|
||||||
// if (erase)
|
|
||||||
// index = DN_FArray_EraseRange(&array, index, -3, DN_ArrayErase_Unstable);
|
|
||||||
// }
|
|
||||||
DN_USize it_index;
|
|
||||||
DN_USize items_erased; // The number of items erased
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T> struct DN_ArrayFindResult
|
|
||||||
{
|
|
||||||
T *data; // Pointer to the value if a match is found, null pointer otherwise
|
|
||||||
DN_USize index; // Index to the value if a match is found, 0 otherwise
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DN_DSMapKeyType
|
|
||||||
{
|
|
||||||
// Key | Key Hash | Map Index
|
|
||||||
DN_DSMapKeyType_Invalid,
|
|
||||||
DN_DSMapKeyType_U64, // U64 | Hash(U64) | Hash(U64) % map_size
|
|
||||||
DN_DSMapKeyType_U64NoHash, // U64 | U64 | U64 % map_size
|
|
||||||
DN_DSMapKeyType_Buffer, // Buffer | Hash(buffer) | Hash(buffer) % map_size
|
|
||||||
DN_DSMapKeyType_BufferAsU64NoHash, // Buffer | U64(buffer[0:4]) | U64(buffer[0:4]) % map_size
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DN_DSMapKey
|
|
||||||
{
|
|
||||||
DN_DSMapKeyType type;
|
|
||||||
DN_U32 hash; // Hash to lookup in the map. If it equals, we check that the original key payload matches
|
|
||||||
void const *buffer_data;
|
|
||||||
DN_U32 buffer_size;
|
|
||||||
DN_U64 u64;
|
|
||||||
bool no_copy_buffer;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct DN_DSMapSlot
|
|
||||||
{
|
|
||||||
DN_DSMapKey key; // Hash table lookup key
|
|
||||||
T value; // Hash table value
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef DN_U32 DN_DSMapFlags;
|
|
||||||
enum DN_DSMapFlags_
|
|
||||||
{
|
|
||||||
DN_DSMapFlags_Nil = 0,
|
|
||||||
DN_DSMapFlags_DontFreeArenaOnResize = 1 << 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
using DN_DSMapHashFunction = DN_U32(DN_DSMapKey key, DN_U32 seed);
|
|
||||||
template <typename T> struct DN_DSMap
|
|
||||||
{
|
|
||||||
DN_U32 *hash_to_slot; // Mapping from hash to a index in the slots array
|
|
||||||
DN_DSMapSlot<T> *slots; // Values of the array stored contiguously, non-sorted order
|
|
||||||
DN_U32 size; // Total capacity of the map and is a power of two
|
|
||||||
DN_U32 occupied; // Number of slots used in the hash table
|
|
||||||
DN_Arena *arena; // Backing arena for the hash table
|
|
||||||
DN_Pool pool; // Allocator for keys that are variable-sized buffers
|
|
||||||
DN_U32 initial_size; // Initial map size, map cannot shrink on erase below this size
|
|
||||||
DN_DSMapHashFunction *hash_function; // Custom hashing function to use if field is set
|
|
||||||
DN_U32 hash_seed; // Seed for the hashing function, when 0, DN_DS_MAP_DEFAULT_HASH_SEED is used
|
|
||||||
DN_DSMapFlags flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T> struct DN_DSMapResult
|
|
||||||
{
|
|
||||||
bool found;
|
|
||||||
DN_DSMapSlot<T> *slot;
|
|
||||||
T *value;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define DN_ISinglyLLDetach(list) (decltype(list))DN_SinglyLLDetach((void **)&(list), (void **)&(list)->next)
|
|
||||||
|
|
||||||
#define DN_SinglyHeadTailLLAppend(head, tail, to_append) \
|
|
||||||
do { \
|
|
||||||
if (!head) \
|
|
||||||
head = to_append; \
|
|
||||||
if (tail) \
|
|
||||||
tail->next = to_append; \
|
|
||||||
tail = to_append; \
|
|
||||||
} while (0)
|
|
||||||
#define DN_ISinglyHeadTailLLAppend(container_ptr, to_append) DN_SinglyHeadTailLLAppend((container_ptr)->head, (container_ptr)->tail, to_append)
|
|
||||||
|
|
||||||
#define DN_SentinelDoublyLLInit(list) (list)->next = (list)->prev = (list)
|
|
||||||
#define DN_SentinelDoublyLLIsSentinel(list, item) ((list) == (item))
|
|
||||||
#define DN_SentinelDoublyLLIsEmpty(list) (!(list) || ((list) == (list)->next))
|
|
||||||
#define DN_SentinelDoublyLLIsInit(list) ((list)->next && (list)->prev)
|
|
||||||
#define DN_SentinelDoublyLLHasItems(list) ((list) && ((list) != (list)->next))
|
|
||||||
#define DN_SentinelDoublyLLForEach(it, list) auto *it = (list)->next; (it) != (list); (it) = (it)->next
|
|
||||||
|
|
||||||
#define DN_SentinelDoublyLLInitArena(list, T, ptr_arena) \
|
|
||||||
do { \
|
|
||||||
(list) = DN_ArenaNew(ptr_arena, T, DN_ZMem_Yes); \
|
|
||||||
DN_SentinelDoublyLLInit(list); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define DN_SentinelDoublyLLInitPool(list, T, pool) \
|
|
||||||
do { \
|
|
||||||
(list) = DN_PoolNew(pool, T); \
|
|
||||||
DN_SentinelDoublyLLInit(list); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define DN_SentinelDoublyLLDetach(item) \
|
|
||||||
do { \
|
|
||||||
if (item) { \
|
|
||||||
(item)->prev->next = (item)->next; \
|
|
||||||
(item)->next->prev = (item)->prev; \
|
|
||||||
(item)->next = nullptr; \
|
|
||||||
(item)->prev = nullptr; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define DN_SentinelDoublyLLDequeue(list, dest_ptr) \
|
|
||||||
if (DN_SentinelDoublyLLHasItems(list)) { \
|
|
||||||
dest_ptr = (list)->next; \
|
|
||||||
DN_SentinelDoublyLLDetach(dest_ptr); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DN_SentinelDoublyLLAppend(list, item) \
|
|
||||||
do { \
|
|
||||||
if (item) { \
|
|
||||||
if ((item)->next) \
|
|
||||||
DN_SentinelDoublyLLDetach(item); \
|
|
||||||
(item)->next = (list)->next; \
|
|
||||||
(item)->prev = (list); \
|
|
||||||
(item)->next->prev = (item); \
|
|
||||||
(item)->prev->next = (item); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define DN_SentinelDoublyLLPrepend(list, item) \
|
|
||||||
do { \
|
|
||||||
if (item) { \
|
|
||||||
if ((item)->next) \
|
|
||||||
DN_SentinelDoublyLLDetach(item); \
|
|
||||||
(item)->next = (list); \
|
|
||||||
(item)->prev = (list)->prev; \
|
|
||||||
(item)->next->prev = (item); \
|
|
||||||
(item)->prev->next = (item); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
// DoublyLL => Non-intrusive Doubly Linked List
|
|
||||||
// A simple doubly linked list where each node has `next` and `prev` pointers.
|
|
||||||
// The head is passed as a pointer-to-pointer to allow head updates.
|
|
||||||
//
|
|
||||||
// struct MyLinkItem {
|
|
||||||
// int data;
|
|
||||||
// MyLinkItem *next;
|
|
||||||
// MyLinkItem *prev;
|
|
||||||
// } *head = nullptr;
|
|
||||||
// DN_DoublyLLAppend(&head, new_item);
|
|
||||||
// for (MyLinkItem *it = head; it; it = it->next) { /* ... */ }
|
|
||||||
|
|
||||||
#define DN_DoublyLLDetach(head, ptr) \
|
|
||||||
do { \
|
|
||||||
if ((head) && (head) == (ptr)) \
|
|
||||||
(head) = (head)->next; \
|
|
||||||
if ((ptr)) { \
|
|
||||||
if ((ptr)->next) \
|
|
||||||
(ptr)->next->prev = (ptr)->prev; \
|
|
||||||
if ((ptr)->prev) \
|
|
||||||
(ptr)->prev->next = (ptr)->next; \
|
|
||||||
(ptr)->prev = (ptr)->next = 0; \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define DN_DoublyLLAppend(head, ptr) \
|
|
||||||
do { \
|
|
||||||
if ((ptr)) { \
|
|
||||||
DN_AssertF((ptr)->prev == 0 && (ptr)->next == 0, "Detach the pointer first"); \
|
|
||||||
(ptr)->prev = (head); \
|
|
||||||
(ptr)->next = 0; \
|
|
||||||
if ((head)) { \
|
|
||||||
(ptr)->next = (head)->next; \
|
|
||||||
(head)->next = (ptr); \
|
|
||||||
} else { \
|
|
||||||
(head) = (ptr); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define DN_DoublyLLPrepend(head, ptr) \
|
|
||||||
do { \
|
|
||||||
if ((ptr)) { \
|
|
||||||
DN_AssertF((ptr)->prev == 0 && (ptr)->next == 0, "Detach the pointer first"); \
|
|
||||||
(ptr)->prev = nullptr; \
|
|
||||||
(ptr)->next = (head); \
|
|
||||||
if ((head)) { \
|
|
||||||
(ptr)->prev = (head)->prev; \
|
|
||||||
(head)->prev = (ptr); \
|
|
||||||
} else { \
|
|
||||||
(head) = (ptr); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
// NOTE: For C++ we need to cast the void* returned in these functions to the concrete type. In C,
|
|
||||||
// no cast is needed.
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
#define DN_CppDeclType(x) decltype(x)
|
|
||||||
#else
|
|
||||||
#define DN_CppDeclType
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DN_PArrayResizeFromPool(ptr, ptr_size, ptr_max, pool, new_max) DN_CArrayResizeFromPool((void **)&(ptr), ptr_size, ptr_max, sizeof((ptr)[0]), pool, new_max)
|
|
||||||
#define DN_PArrayResizeFromArena(ptr, ptr_size, ptr_max, arena, new_max) DN_CArrayResizeFromArena((void **)&(ptr), ptr_size, ptr_max, sizeof((ptr)[0]), arena, new_max)
|
|
||||||
#define DN_PArrayGrowFromPool(ptr, size, ptr_max, pool, new_max) DN_CArrayGrowFromPool((void **)&(ptr), size, ptr_max, sizeof((ptr)[0]), pool, new_max)
|
|
||||||
#define DN_PArrayGrowFromArena(ptr, size, ptr_max, arena, new_max) DN_CArrayGrowFromArena((void **)&(ptr), size, ptr_max, sizeof((ptr)[0]), arena, new_max)
|
|
||||||
#define DN_PArrayGrowIfNeededFromPool(ptr, size, ptr_max, pool, add_count) DN_CArrayGrowIfNeededFromPool((void **)(ptr), size, ptr_max, sizeof((*ptr)[0]), pool, add_count)
|
|
||||||
#define DN_PArrayGrowIfNeededFromArena(ptr, size, ptr_max, arena, add_count) DN_CArrayGrowIfNeededFromArena((void **)(ptr), size, ptr_max, sizeof((*ptr)[0]), arena, add_count)
|
|
||||||
#define DN_PArrayMakeArray(ptr, ptr_size, max, count, z_mem) (DN_CppDeclType(&(ptr)[0]))DN_CArrayMakeArray(ptr, ptr_size, max, sizeof((ptr)[0]), count, z_mem)
|
|
||||||
#define DN_PArrayMakeArrayZ(ptr, ptr_size, max, count) (DN_CppDeclType(&(ptr)[0]))DN_CArrayMakeArray(ptr, ptr_size, max, sizeof((ptr)[0]), count, DN_ZMem_Yes)
|
|
||||||
#define DN_PArrayMake(ptr, ptr_size, max, z_mem) (DN_CppDeclType(&(ptr)[0]))DN_CArrayMakeArray(ptr, ptr_size, max, sizeof((ptr)[0]), 1, z_mem)
|
|
||||||
#define DN_PArrayMakeZ(ptr, ptr_size, max) (DN_CppDeclType(&(ptr)[0]))DN_CArrayMakeArray(ptr, ptr_size, max, sizeof((ptr)[0]), 1, DN_ZMem_Yes)
|
|
||||||
#define DN_PArrayAddArray(ptr, ptr_size, max, items, count, add) (DN_CppDeclType(&(ptr)[0]))DN_CArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), items, count, add)
|
|
||||||
#define DN_PArrayAdd(ptr, ptr_size, max, item, add) (DN_CppDeclType(&(ptr)[0]))DN_CArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), &item, 1, add)
|
|
||||||
#define DN_PArrayAppendArray(ptr, ptr_size, max, items, count) (DN_CppDeclType(&(ptr)[0]))DN_CArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), items, count, DN_ArrayAdd_Append)
|
|
||||||
#define DN_PArrayAppend(ptr, ptr_size, max, item) (DN_CppDeclType(&(ptr)[0]))DN_CArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), &item, 1, DN_ArrayAdd_Append)
|
|
||||||
#define DN_PArrayPrependArray(ptr, ptr_size, max, items, count) (DN_CppDeclType(&(ptr)[0]))DN_CArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), items, count, DN_ArrayAdd_Prepend)
|
|
||||||
#define DN_PArrayPrepend(ptr, ptr_size, max, item) (DN_CppDeclType(&(ptr)[0]))DN_CArrayAddArray(ptr, ptr_size, max, sizeof((ptr)[0]), &item, 1, DN_ArrayAdd_Prepend)
|
|
||||||
#define DN_PArrayEraseRange(ptr, ptr_size, begin_index, count, erase) DN_CArrayEraseRange(ptr, ptr_size, sizeof((ptr)[0]), begin_index, count, erase)
|
|
||||||
#define DN_PArrayErase(ptr, ptr_size, index, erase) DN_CArrayEraseRange(ptr, ptr_size, sizeof((ptr)[0]), index, 1, erase)
|
|
||||||
#define DN_PArrayInsertArray(ptr, ptr_size, max, index, items, count) (DN_CppDeclType(&(ptr)[0]))DN_CArrayInsertArray(ptr, ptr_size, max, sizeof((ptr)[0]), index, items, count)
|
|
||||||
#define DN_PArrayInsert(ptr, ptr_size, max, index, item) (DN_CppDeclType(&(ptr)[0]))DN_CArrayInsertArray(ptr, ptr_size, max, sizeof((ptr)[0]), index, &item, 1)
|
|
||||||
#define DN_PArrayPopFront(ptr, ptr_size, max, count) (DN_CppDeclType(&(ptr)[0]))DN_CArrayPopFront(ptr, ptr_size, sizeof((ptr)[0]), count)
|
|
||||||
#define DN_PArrayPopBack(ptr, ptr_size, max, count) (DN_CppDeclType(&(ptr)[0]))DN_CArrayPopBack(ptr, ptr_size, sizeof((ptr)[0]), count)
|
|
||||||
|
|
||||||
#define DN_LArrayResizeFromPool(c_array, size, pool, new_max) DN_PArrayResizeFromPool(c_array, size, DN_ArrayCountU(c_array), pool, new_max)
|
|
||||||
#define DN_LArrayResizeFromArena(c_array, size, arena, new_max) DN_PArrayResizeFromArena(c_array, size, DN_ArrayCountU(c_array), arena, new_max)
|
|
||||||
#define DN_LArrayGrowFromPool(c_array, size, pool, new_max) DN_PArrayGrowFromPool(c_array, size, DN_ArrayCountU(c_array), pool, new_max)
|
|
||||||
#define DN_LArrayGrowFromArena(c_array, size, arena, new_max) DN_PArrayGrowFromArena(c_array, size, DN_ArrayCountU(c_array), arena, new_max)
|
|
||||||
#define DN_LArrayGrowIfNeededFromPool(c_array, size, pool, add_count) DN_PArrayGrowIfNeededFromPool(c_array, size, DN_ArrayCountU(c_array), pool, add_count)
|
|
||||||
#define DN_LArrayGrowIfNeededFromArena(c_array, size, arena, add_count) DN_PArrayGrowIfNeededFromArena(c_array, size, DN_ArrayCountU(c_array), arena, add_count)
|
|
||||||
#define DN_LArrayMakeArray(c_array, ptr_size, count, z_mem) DN_PArrayMakeArray(c_array, ptr_size, DN_ArrayCountU(c_array), count, z_mem)
|
|
||||||
#define DN_LArrayMakeArrayZ(c_array, ptr_size, count) DN_PArrayMakeArrayZ(c_array, ptr_size, DN_ArrayCountU(c_array), count)
|
|
||||||
#define DN_LArrayMake(c_array, ptr_size, z_mem) DN_PArrayMake(c_array, ptr_size, DN_ArrayCountU(c_array), z_mem)
|
|
||||||
#define DN_LArrayMakeZ(c_array, ptr_size) DN_PArrayMakeZ(c_array, ptr_size, DN_ArrayCountU(c_array))
|
|
||||||
#define DN_LArrayAddArray(c_array, ptr_size, items, count, add) DN_PArrayAddArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count, add)
|
|
||||||
#define DN_LArrayAdd(c_array, ptr_size, item, add) DN_PArrayAdd(c_array, ptr_size, DN_ArrayCountU(c_array), item, add)
|
|
||||||
#define DN_LArrayAppendArray(c_array, ptr_size, items, count) DN_PArrayAppendArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count)
|
|
||||||
#define DN_LArrayAppend(c_array, ptr_size, item) DN_PArrayAppend(c_array, ptr_size, DN_ArrayCountU(c_array), item)
|
|
||||||
#define DN_LArrayPrependArray(c_array, ptr_size, items, count) DN_PArrayPrependArray(c_array, ptr_size, DN_ArrayCountU(c_array), items, count)
|
|
||||||
#define DN_LArrayPrepend(c_array, ptr_size, item) DN_PArrayPrepend(c_array, ptr_size, DN_ArrayCountU(c_array), item)
|
|
||||||
#define DN_LArrayEraseRange(c_array, ptr_size, begin_index, count, erase) DN_PArrayEraseRange(c_array, ptr_size, begin_index, count, erase)
|
|
||||||
#define DN_LArrayErase(c_array, ptr_size, index, erase) DN_PArrayErase(c_array, ptr_size, index, erase)
|
|
||||||
#define DN_LArrayInsertArray(c_array, ptr_size, index, items, count) DN_PArrayInsertArray(c_array, ptr_size, DN_ArrayCountU(c_array), index, items, count)
|
|
||||||
#define DN_LArrayInsert(c_array, ptr_size, index, item) DN_PArrayInsert(c_array, ptr_size, DN_ArrayCountU(c_array), index, item)
|
|
||||||
#define DN_LArrayPopFront(c_array, ptr_size, count) DN_PArrayPopFront(c_array, ptr_size, DN_ArrayCountU(c_array), count)
|
|
||||||
#define DN_LArrayPopBack(c_array, ptr_size, count) DN_PArrayPopBack(c_array, ptr_size, DN_ArrayCountU(c_array), count)
|
|
||||||
|
|
||||||
#define DN_IArrayResizeFromPool(ptr_array, pool, new_max) DN_CArrayResizeFromPool((void **)(&(ptr_array)->data), &(ptr_array)->size, &(ptr_array)->max, sizeof((ptr_array)->data[0]), pool, new_max)
|
|
||||||
#define DN_IArrayResizeFromArena(ptr_array, arena, new_max) DN_CArrayResizeFromArena((void **)(&(ptr_array)->data), &(ptr_array)->size, &(ptr_array)->max, sizeof((ptr_array)->data[0]), arena, new_max)
|
|
||||||
#define DN_IArrayGrowFromPool(ptr_array, pool, new_max) DN_CArrayGrowFromPool((void **)(&(ptr_array)->data), (ptr_array)->size, &(ptr_array)->max, sizeof((ptr_array)->data[0]), pool, new_max)
|
|
||||||
#define DN_IArrayGrowFromArena(ptr_array, arena, new_max) DN_CArrayGrowFromArena((void **)(&(ptr_array)->data), (ptr_array)->size, &(ptr_array)->max, sizeof((ptr_array)->data[0]), arena, new_max)
|
|
||||||
#define DN_IArrayGrowIfNeededFromPool(ptr_array, pool, add_count) DN_CArrayGrowIfNeededFromPool((void **)(&(ptr_array)->data), (ptr_array)->size, &(ptr_array)->max, sizeof((ptr_array)->data[0]), pool, add_count)
|
|
||||||
#define DN_IArrayGrowIfNeededFromArena(ptr_array, arena, add_count) DN_CArrayGrowIfNeededFromArena((void **)(&(ptr_array)->data), (ptr_array)->size, &(ptr_array)->max, sizeof((ptr_array)->data[0]), arena, add_count)
|
|
||||||
#define DN_IArrayMakeArray(ptr_array, count, z_mem) (DN_CppDeclType(&((ptr_array)->data)[0]))DN_CArrayMakeArray((ptr_array)->data, &(ptr_array)->size, (ptr_array)->max, sizeof(((ptr_array)->data)[0]), count, z_mem)
|
|
||||||
#define DN_IArrayMakeArrayZ(ptr_array, count) (DN_CppDeclType(&((ptr_array)->data)[0]))DN_CArrayMakeArray((ptr_array)->data, &(ptr_array)->size, (ptr_array)->max, sizeof(((ptr_array)->data)[0]), count, DN_ZMem_Yes)
|
|
||||||
#define DN_IArrayMake(ptr_array, z_mem) (DN_CppDeclType(&((ptr_array)->data)[0]))DN_CArrayMakeArray((ptr_array)->data, &(ptr_array)->size, (ptr_array)->max, sizeof(((ptr_array)->data)[0]), 1, z_mem)
|
|
||||||
#define DN_IArrayMakeZ(ptr_array) (DN_CppDeclType(&((ptr_array)->data)[0]))DN_CArrayMakeArray((ptr_array)->data, &(ptr_array)->size, (ptr_array)->max, sizeof(((ptr_array)->data)[0]), 1, DN_ZMem_Yes)
|
|
||||||
#define DN_IArrayAddArray(ptr_array, items, count, add) (DN_CppDeclType(&((ptr_array)->data)[0]))DN_CArrayAddArray((ptr_array)->data, &(ptr_array)->size, (ptr_array)->max, sizeof(((ptr_array)->data)[0]), items, count, add)
|
|
||||||
#define DN_IArrayAdd(ptr_array, item, add) (DN_CppDeclType(&((ptr_array)->data)[0]))DN_CArrayAddArray((ptr_array)->data, &(ptr_array)->size, (ptr_array)->max, sizeof(((ptr_array)->data)[0]), &item, 1, add)
|
|
||||||
#define DN_IArrayAppendArray(ptr_array, items, count) (DN_CppDeclType(&((ptr_array)->data)[0]))DN_CArrayAddArray((ptr_array)->data, &(ptr_array)->size, (ptr_array)->max, sizeof(((ptr_array)->data)[0]), items, count, DN_ArrayAdd_Append)
|
|
||||||
#define DN_IArrayAppend(ptr_array, item) (DN_CppDeclType(&((ptr_array)->data)[0]))DN_CArrayAddArray((ptr_array)->data, &(ptr_array)->size, (ptr_array)->max, sizeof(((ptr_array)->data)[0]), &item, 1, DN_ArrayAdd_Append)
|
|
||||||
#define DN_IArrayPrependArray(ptr_array, items, count) (DN_CppDeclType(&((ptr_array)->data)[0]))DN_CArrayAddArray((ptr_array)->data, &(ptr_array)->size, (ptr_array)->max, sizeof(((ptr_array)->data)[0]), items, count, DN_ArrayAdd_Prepend)
|
|
||||||
#define DN_IArrayPrepend(ptr_array, item) (DN_CppDeclType(&((ptr_array)->data)[0]))DN_CArrayAddArray((ptr_array)->data, &(ptr_array)->size, (ptr_array)->max, sizeof(((ptr_array)->data)[0]), &item, 1, DN_ArrayAdd_Prepend)
|
|
||||||
#define DN_IArrayEraseRange(ptr_array, begin_index, count, erase) DN_CArrayEraseRange((ptr_array)->data, &(ptr_array)->size, sizeof(((ptr_array)->data)[0]), begin_index, count, erase)
|
|
||||||
#define DN_IArrayErase(ptr_array, index, erase) DN_CArrayEraseRange((ptr_array)->data, &(ptr_array)->size, sizeof(((ptr_array)->data)[0]), index, 1, erase)
|
|
||||||
#define DN_IArrayInsertArray(ptr_array, index, items, count) (DN_CppDeclType(&((ptr_array)->data)[0]))DN_CArrayInsertArray((ptr_array)->data, &(ptr_array)->size, (ptr_array)->max, sizeof(((ptr_array)->data)[0]), index, items, count)
|
|
||||||
#define DN_IArrayInsert(ptr_array, index, item, count) (DN_CppDeclType(&((ptr_array)->data)[0]))DN_CArrayInsertArray((ptr_array)->data, &(ptr_array)->size, (ptr_array)->max, sizeof(((ptr_array)->data)[0]), index, &item, 1)
|
|
||||||
#define DN_IArrayPopFront(ptr_array, count) (DN_CppDeclType(&((ptr_array)->data)[0]))DN_CArrayPopFront((ptr_array)->data, &(ptr_array)->size, sizeof(((ptr_array)->data)[0]), count)
|
|
||||||
#define DN_IArrayPopBack(ptr_array, count) (DN_CppDeclType(&((ptr_array)->data)[0]))DN_CArrayPopBack((ptr_array)->data, &(ptr_array)->size, sizeof(((ptr_array)->data)[0]), count)
|
|
||||||
|
|
||||||
#define DN_ISliceAllocArena(slice_ptr, count_, zmem, arena) (DN_CppDeclType(&((slice_ptr)->data[0])))DN_SliceAllocArena((void **)&((slice_ptr)->data), &((slice_ptr)->count), count_, sizeof((slice_ptr)->data[0]), alignof(DN_CppDeclType((slice_ptr)->data[0])), zmem, arena)
|
|
||||||
|
|
||||||
DN_API void* DN_SliceAllocArena (void **data, DN_USize *slice_size_field, DN_USize size, DN_USize elem_size, DN_U8 align, DN_ZMem zmem, DN_Arena *arena);
|
|
||||||
|
|
||||||
DN_API void* DN_CArrayInsertArray (void *data, DN_USize *size, DN_USize max, DN_USize elem_size, DN_USize index, void const *items, DN_USize count);
|
|
||||||
DN_API void* DN_CArrayPopFront (void *data, DN_USize *size, DN_USize elem_size, DN_USize count);
|
|
||||||
DN_API void* DN_CArrayPopBack (void *data, DN_USize *size, DN_USize elem_size, DN_USize count);
|
|
||||||
DN_API DN_ArrayEraseResult DN_CArrayEraseRange (void *data, DN_USize *size, DN_USize elem_size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase);
|
|
||||||
DN_API void* DN_CArrayMakeArray (void *data, DN_USize *size, DN_USize max, DN_USize data_size, DN_USize make_size, DN_ZMem z_mem);
|
|
||||||
DN_API void* DN_CArrayAddArray (void *data, DN_USize *size, DN_USize max, DN_USize data_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add);
|
|
||||||
DN_API bool DN_CArrayResizeFromPool (void **data, DN_USize *size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize new_max);
|
|
||||||
DN_API bool DN_CArrayResizeFromArena (void **data, DN_USize *size, DN_USize *max, DN_USize data_size, DN_Arena *arena, DN_USize new_max);
|
|
||||||
DN_API bool DN_CArrayGrowFromPool (void **data, DN_USize size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize new_max);
|
|
||||||
DN_API bool DN_CArrayGrowFromArena (void **data, DN_USize size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize new_max);
|
|
||||||
DN_API bool DN_CArrayGrowIfNeededFromPool (void **data, DN_USize size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize add_count);
|
|
||||||
DN_API bool DN_CArrayGrowIfNeededFromArena (void **data, DN_USize size, DN_USize *max, DN_USize data_size, DN_Arena *pool, DN_USize add_count);
|
|
||||||
|
|
||||||
DN_API void* DN_SinglyLLDetach (void **link, void **next);
|
|
||||||
|
|
||||||
DN_API bool DN_RingHasSpace (DN_Ring const *ring, DN_U64 size);
|
|
||||||
DN_API bool DN_RingHasData (DN_Ring const *ring, DN_U64 size);
|
|
||||||
DN_API void DN_RingWrite (DN_Ring *ring, void const *src, DN_U64 src_size);
|
|
||||||
#define DN_RingWriteStruct(ring, item) DN_RingWrite((ring), (item), sizeof(*(item)))
|
|
||||||
DN_API void DN_RingRead (DN_Ring *ring, void *dest, DN_U64 dest_size);
|
|
||||||
#define DN_RingReadStruct(ring, dest) DN_RingRead((ring), (dest), sizeof(*(dest)))
|
|
||||||
|
|
||||||
DN_U32 const DN_DS_MAP_DEFAULT_HASH_SEED = 0x8a1ced49;
|
|
||||||
DN_U32 const DN_DS_MAP_SENTINEL_SLOT = 0;
|
|
||||||
|
|
||||||
template <typename T> DN_DSMap<T> DN_DSMapInit (DN_Arena *arena, DN_U32 size, DN_DSMapFlags flags);
|
|
||||||
template <typename T> void DN_DSMapDeinit (DN_DSMap<T> *map, DN_ZMem z_mem);
|
|
||||||
template <typename T> bool DN_DSMapIsValid (DN_DSMap<T> const *map);
|
|
||||||
template <typename T> DN_U32 DN_DSMapHash (DN_DSMap<T> const *map, DN_DSMapKey key);
|
|
||||||
template <typename T> DN_U32 DN_DSMapHashToSlotIndex (DN_DSMap<T> const *map, DN_DSMapKey key);
|
|
||||||
template <typename T> DN_DSMapResult<T> DN_DSMapFind (DN_DSMap<T> const *map, DN_DSMapKey key);
|
|
||||||
template <typename T> DN_DSMapResult<T> DN_DSMapMake (DN_DSMap<T> *map, DN_DSMapKey key);
|
|
||||||
template <typename T> DN_DSMapResult<T> DN_DSMapSet (DN_DSMap<T> *map, DN_DSMapKey key, T const &value);
|
|
||||||
template <typename T> DN_DSMapResult<T> DN_DSMapFindKeyU64 (DN_DSMap<T> const *map, DN_U64 key);
|
|
||||||
template <typename T> DN_DSMapResult<T> DN_DSMapMakeKeyU64 (DN_DSMap<T> *map, DN_U64 key);
|
|
||||||
template <typename T> DN_DSMapResult<T> DN_DSMapSetKeyU64 (DN_DSMap<T> *map, DN_U64 key, T const &value);
|
|
||||||
template <typename T> DN_DSMapResult<T> DN_DSMapFindKeyStr8 (DN_DSMap<T> const *map, DN_Str8 key);
|
|
||||||
template <typename T> DN_DSMapResult<T> DN_DSMapMakeKeyStr8 (DN_DSMap<T> *map, DN_Str8 key);
|
|
||||||
template <typename T> DN_DSMapResult<T> DN_DSMapSetKeyStr8 (DN_DSMap<T> *map, DN_Str8 key, T const &value);
|
|
||||||
template <typename T> bool DN_DSMapResize (DN_DSMap<T> *map, DN_U32 size);
|
|
||||||
template <typename T> bool DN_DSMapErase (DN_DSMap<T> *map, DN_DSMapKey key);
|
|
||||||
template <typename T> bool DN_DSMapEraseKeyU64 (DN_DSMap<T> *map, DN_U64 key);
|
|
||||||
template <typename T> bool DN_DSMapEraseKeyStr8 (DN_DSMap<T> *map, DN_Str8 key);
|
|
||||||
template <typename T> DN_DSMapKey DN_DSMapKeyBuffer (DN_DSMap<T> const *map, void const *data, DN_USize size);
|
|
||||||
template <typename T> DN_DSMapKey DN_DSMapKeyBufferAsU64NoHash (DN_DSMap<T> const *map, void const *data, DN_USize size);
|
|
||||||
template <typename T> DN_DSMapKey DN_DSMapKeyU64 (DN_DSMap<T> const *map, DN_U64 u64);
|
|
||||||
template <typename T> DN_DSMapKey DN_DSMapKeyStr8 (DN_DSMap<T> const *map, DN_Str8 string);
|
|
||||||
#define DN_DSMapKeyCStr8(map, string) DN_DSMapKeyBuffer(map, string, sizeof((string))/sizeof((string)[0]) - 1)
|
|
||||||
DN_API DN_DSMapKey DN_DSMapKeyU64NoHash (DN_U64 u64);
|
|
||||||
DN_API bool DN_DSMapKeyEquals (DN_DSMapKey lhs, DN_DSMapKey rhs);
|
|
||||||
DN_API bool operator== (DN_DSMapKey lhs, DN_DSMapKey rhs);
|
|
||||||
#endif // !defined(DN_CONTAINER_H)
|
|
||||||
@@ -10,19 +10,15 @@ DN_API void DN_LeakTrackAlloc_(DN_LeakTracker *leak, void *ptr, DN_USize size, b
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
DN_TicketMutex_Begin(&leak->alloc_table_mutex);
|
DN_TicketMutex_Begin(&leak->alloc_table_mutex);
|
||||||
DN_DEFER
|
|
||||||
{
|
|
||||||
DN_TicketMutex_End(&leak->alloc_table_mutex);
|
|
||||||
};
|
|
||||||
|
|
||||||
DN_Str8 stack_trace = DN_StackTraceWalkStr8FromHeap(128, 3 /*skip*/);
|
DN_Str8 stack_trace = DN_Str8FromStackTraceNowHeap(128, 3 /*skip*/);
|
||||||
DN_DSMap<DN_LeakAlloc> *alloc_table = &leak->alloc_table;
|
DN_DSMap<DN_LeakAlloc> *alloc_table = &leak->alloc_table;
|
||||||
DN_DSMapResult<DN_LeakAlloc> alloc_entry = DN_DSMapMakeKeyU64(alloc_table, DN_Cast(DN_U64) ptr);
|
DN_DSMapResult<DN_LeakAlloc> alloc_entry = DN_DSMapMakeKeyU64(alloc_table, DN_Cast(DN_U64) ptr);
|
||||||
DN_LeakAlloc *alloc = alloc_entry.value;
|
DN_LeakAlloc *alloc = alloc_entry.value;
|
||||||
if (alloc_entry.found) {
|
if (alloc_entry.found) {
|
||||||
if ((alloc->flags & DN_LeakAllocFlag_Freed) == 0) {
|
if ((alloc->flags & DN_LeakAllocFlag_Freed) == 0) {
|
||||||
DN_Str8x32 alloc_size = DN_ByteCountStr8x32(alloc->size);
|
DN_Str8x32 alloc_size = DN_Str8x32FromByteCountU64Auto(alloc->size);
|
||||||
DN_Str8x32 new_alloc_size = DN_ByteCountStr8x32(size);
|
DN_Str8x32 new_alloc_size = DN_Str8x32FromByteCountU64Auto(size);
|
||||||
DN_HardAssertF(
|
DN_HardAssertF(
|
||||||
alloc->flags & DN_LeakAllocFlag_Freed,
|
alloc->flags & DN_LeakAllocFlag_Freed,
|
||||||
"This pointer is already in the leak tracker, however it has not been freed yet. This "
|
"This pointer is already in the leak tracker, however it has not been freed yet. This "
|
||||||
@@ -58,6 +54,7 @@ DN_API void DN_LeakTrackAlloc_(DN_LeakTracker *leak, void *ptr, DN_USize size, b
|
|||||||
alloc->stack_trace = stack_trace;
|
alloc->stack_trace = stack_trace;
|
||||||
alloc->flags |= leak_permitted ? DN_LeakAllocFlag_LeakPermitted : 0;
|
alloc->flags |= leak_permitted ? DN_LeakAllocFlag_LeakPermitted : 0;
|
||||||
leak->alloc_table_bytes_allocated_for_stack_traces += alloc->stack_trace.size;
|
leak->alloc_table_bytes_allocated_for_stack_traces += alloc->stack_trace.size;
|
||||||
|
DN_TicketMutex_End(&leak->alloc_table_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr)
|
DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr)
|
||||||
@@ -66,12 +63,8 @@ DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
DN_TicketMutex_Begin(&leak->alloc_table_mutex);
|
DN_TicketMutex_Begin(&leak->alloc_table_mutex);
|
||||||
DN_DEFER
|
|
||||||
{
|
|
||||||
DN_TicketMutex_End(&leak->alloc_table_mutex);
|
|
||||||
};
|
|
||||||
|
|
||||||
DN_Str8 stack_trace = DN_StackTraceWalkStr8FromHeap(128, 3 /*skip*/);
|
DN_Str8 stack_trace = DN_Str8FromStackTraceNowHeap(128, 3 /*skip*/);
|
||||||
DN_DSMap<DN_LeakAlloc> *alloc_table = &leak->alloc_table;
|
DN_DSMap<DN_LeakAlloc> *alloc_table = &leak->alloc_table;
|
||||||
DN_DSMapResult<DN_LeakAlloc> alloc_entry = DN_DSMapFindKeyU64(alloc_table, DN_Cast(uintptr_t) ptr);
|
DN_DSMapResult<DN_LeakAlloc> alloc_entry = DN_DSMapFindKeyU64(alloc_table, DN_Cast(uintptr_t) ptr);
|
||||||
DN_HardAssertF(alloc_entry.found,
|
DN_HardAssertF(alloc_entry.found,
|
||||||
@@ -82,7 +75,7 @@ DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr)
|
|||||||
|
|
||||||
DN_LeakAlloc *alloc = alloc_entry.value;
|
DN_LeakAlloc *alloc = alloc_entry.value;
|
||||||
if (alloc->flags & DN_LeakAllocFlag_Freed) {
|
if (alloc->flags & DN_LeakAllocFlag_Freed) {
|
||||||
DN_Str8x32 freed_size = DN_ByteCountStr8x32(alloc->freed_size);
|
DN_Str8x32 freed_size = DN_Str8x32FromByteCountU64Auto(alloc->freed_size);
|
||||||
DN_HardAssertF((alloc->flags & DN_LeakAllocFlag_Freed) == 0,
|
DN_HardAssertF((alloc->flags & DN_LeakAllocFlag_Freed) == 0,
|
||||||
"Double free detected, pointer to free was already marked "
|
"Double free detected, pointer to free was already marked "
|
||||||
"as freed. Either the pointer was reallocated but not "
|
"as freed. Either the pointer was reallocated but not "
|
||||||
@@ -110,6 +103,7 @@ DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr)
|
|||||||
alloc->flags |= DN_LeakAllocFlag_Freed;
|
alloc->flags |= DN_LeakAllocFlag_Freed;
|
||||||
alloc->freed_stack_trace = stack_trace;
|
alloc->freed_stack_trace = stack_trace;
|
||||||
leak->alloc_table_bytes_allocated_for_stack_traces += alloc->freed_stack_trace.size;
|
leak->alloc_table_bytes_allocated_for_stack_traces += alloc->freed_stack_trace.size;
|
||||||
|
DN_TicketMutex_End(&leak->alloc_table_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API void DN_LeakDump_(DN_LeakTracker *leak)
|
DN_API void DN_LeakDump_(DN_LeakTracker *leak)
|
||||||
@@ -124,7 +118,7 @@ DN_API void DN_LeakDump_(DN_LeakTracker *leak)
|
|||||||
if (alloc_leaked && !leak_permitted) {
|
if (alloc_leaked && !leak_permitted) {
|
||||||
leaked_bytes += alloc->size;
|
leaked_bytes += alloc->size;
|
||||||
leak_count++;
|
leak_count++;
|
||||||
DN_Str8x32 alloc_size = DN_ByteCountStr8x32(alloc->size);
|
DN_Str8x32 alloc_size = DN_Str8x32FromByteCountU64Auto(alloc->size);
|
||||||
DN_LogWarningF(
|
DN_LogWarningF(
|
||||||
"Pointer (0x%p) leaked %.*s at:\n"
|
"Pointer (0x%p) leaked %.*s at:\n"
|
||||||
"%.*s",
|
"%.*s",
|
||||||
@@ -135,7 +129,7 @@ DN_API void DN_LeakDump_(DN_LeakTracker *leak)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (leak_count) {
|
if (leak_count) {
|
||||||
DN_Str8x32 leak_size = DN_ByteCountStr8x32(leaked_bytes);
|
DN_Str8x32 leak_size = DN_Str8x32FromByteCountU64Auto(leaked_bytes);
|
||||||
DN_LogWarningF("There were %I64u leaked allocations totalling %.*s", leak_count, DN_Str8PrintFmt(leak_size));
|
DN_LogWarningF("There were %I64u leaked allocations totalling %.*s", leak_count, DN_Str8PrintFmt(leak_size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -201,6 +201,6 @@ DN_API void DN_BinPackCBuffer(DN_BinPack *pack, DN_BinPackMode mode, char *ptr,
|
|||||||
|
|
||||||
DN_API DN_Str8 DN_BinPackBuild(DN_BinPack const *pack, DN_Arena *arena)
|
DN_API DN_Str8 DN_BinPackBuild(DN_BinPack const *pack, DN_Arena *arena)
|
||||||
{
|
{
|
||||||
DN_Str8 result = DN_Str8BuilderBuild(&pack->writer, arena);
|
DN_Str8 result = DN_Str8FromStr8BuilderArena(&pack->writer, arena);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ DN_API DN_JSONBuilder DN_JSONBuilder_Init(DN_Arena *arena, int spaces_per_indent
|
|||||||
|
|
||||||
DN_API DN_Str8 DN_JSONBuilder_Build(DN_JSONBuilder const *builder, DN_Arena *arena)
|
DN_API DN_Str8 DN_JSONBuilder_Build(DN_JSONBuilder const *builder, DN_Arena *arena)
|
||||||
{
|
{
|
||||||
DN_Str8 result = DN_Str8BuilderBuild(&builder->string_builder, arena);
|
DN_Str8 result = DN_Str8FromStr8BuilderArena(&builder->string_builder, arena);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ DN_API void DN_JSONBuilder_KeyValue(DN_JSONBuilder *builder, DN_Str8 key, DN_Str
|
|||||||
|
|
||||||
DN_API void DN_JSONBuilder_KeyValueFV(DN_JSONBuilder *builder, DN_Str8 key, char const *value_fmt, va_list args)
|
DN_API void DN_JSONBuilder_KeyValueFV(DN_JSONBuilder *builder, DN_Str8 key, char const *value_fmt, va_list args)
|
||||||
{
|
{
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(&builder->string_builder.arena, 1);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(&builder->string_builder.arena, 1);
|
||||||
DN_Str8 value = DN_Str8FromFmtVArena(&scratch.arena, value_fmt, args);
|
DN_Str8 value = DN_Str8FromFmtVArena(&scratch.arena, value_fmt, args);
|
||||||
DN_JSONBuilder_KeyValue(builder, key, value);
|
DN_JSONBuilder_KeyValue(builder, key, value);
|
||||||
DN_TCScratchEnd(&scratch);
|
DN_TCScratchEnd(&scratch);
|
||||||
|
|||||||
@@ -79,15 +79,12 @@ enum DN_BinarySearchType
|
|||||||
|
|
||||||
struct DN_BinarySearchResult
|
struct DN_BinarySearchResult
|
||||||
{
|
{
|
||||||
bool found;
|
bool found;
|
||||||
DN_USize index;
|
DN_USize index;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using DN_QSortLessThanProc = bool(T const &a, T const &b, void *user_context);
|
|
||||||
|
|
||||||
#if !defined(DN_NO_JSON_BUILDER)
|
#if !defined(DN_NO_JSON_BUILDER)
|
||||||
// NOTE: DN_JSONBuilder ////////////////////////////////////////////////////////////////////////////
|
// NOTE: DN_JSONBuilder
|
||||||
#define DN_JSONBuilder_Object(builder) \
|
#define DN_JSONBuilder_Object(builder) \
|
||||||
DN_DeferLoop(DN_JSONBuilder_ObjectBegin(builder), \
|
DN_DeferLoop(DN_JSONBuilder_ObjectBegin(builder), \
|
||||||
DN_JSONBuilder_ObjectEnd(builder))
|
DN_JSONBuilder_ObjectEnd(builder))
|
||||||
@@ -133,10 +130,6 @@ DN_API void DN_JSONBuilder_BoolNamed (DN_JSONBuilde
|
|||||||
template <typename T> bool DN_BinarySearch_DefaultLessThan(T const &lhs, T const &rhs);
|
template <typename T> bool DN_BinarySearch_DefaultLessThan(T const &lhs, T const &rhs);
|
||||||
template <typename T> DN_BinarySearchResult DN_BinarySearch (T const *array, DN_USize array_size, T const &find, DN_BinarySearchType type = DN_BinarySearchType_Match, DN_BinarySearchLessThanProc<T> less_than = DN_BinarySearch_DefaultLessThan);
|
template <typename T> DN_BinarySearchResult DN_BinarySearch (T const *array, DN_USize array_size, T const &find, DN_BinarySearchType type = DN_BinarySearchType_Match, DN_BinarySearchLessThanProc<T> less_than = DN_BinarySearch_DefaultLessThan);
|
||||||
|
|
||||||
// NOTE: DN_QSort
|
|
||||||
template <typename T> bool DN_QSort_DefaultLessThan(T const &lhs, T const &rhs, void *user_context);
|
|
||||||
template <typename T> void DN_QSort (T *array, DN_USize array_size, void *user_context, DN_QSortLessThanProc<T> less_than = DN_QSort_DefaultLessThan);
|
|
||||||
|
|
||||||
// NOTE: DN_BinarySearch
|
// NOTE: DN_BinarySearch
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool DN_BinarySearch_DefaultLessThan(T const &lhs, T const &rhs)
|
bool DN_BinarySearch_DefaultLessThan(T const &lhs, T const &rhs)
|
||||||
@@ -189,76 +182,4 @@ DN_BinarySearchResult DN_BinarySearch(T const *array,
|
|||||||
result.index = first - array;
|
result.index = first - array;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: DN_QSort //////////////////////////////////////////////////////////////////////////////////
|
|
||||||
template <typename T>
|
|
||||||
bool DN_QSort_DefaultLessThan(T const &lhs, T const &rhs, void *user_context)
|
|
||||||
{
|
|
||||||
(void)user_context;
|
|
||||||
bool result = lhs < rhs;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void DN_QSort(T *array, DN_USize array_size, void *user_context, DN_QSortLessThanProc<T> less_than)
|
|
||||||
{
|
|
||||||
if (!array || array_size <= 1 || !less_than)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// NOTE: Insertion Sort, under 24->32 is an optimal amount /////////////////////////////////////
|
|
||||||
const DN_USize QSORT_THRESHOLD = 24;
|
|
||||||
if (array_size < QSORT_THRESHOLD) {
|
|
||||||
for (DN_USize item_to_insert_index = 1; item_to_insert_index < array_size; item_to_insert_index++) {
|
|
||||||
for (DN_USize index = 0; index < item_to_insert_index; index++) {
|
|
||||||
if (!less_than(array[index], array[item_to_insert_index], user_context)) {
|
|
||||||
T item_to_insert = array[item_to_insert_index];
|
|
||||||
for (DN_USize i = item_to_insert_index; i > index; i--)
|
|
||||||
array[i] = array[i - 1];
|
|
||||||
|
|
||||||
array[index] = item_to_insert;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: Quick sort, under 24->32 is an optimal amount /////////////////////////////////////////
|
|
||||||
DN_USize last_index = array_size - 1;
|
|
||||||
DN_USize pivot_index = array_size / 2;
|
|
||||||
DN_USize partition_index = 0;
|
|
||||||
DN_USize start_index = 0;
|
|
||||||
|
|
||||||
// Swap pivot with last index, so pivot is always at the end of the array.
|
|
||||||
// This makes logic much simpler.
|
|
||||||
DN_Swap(array[last_index], array[pivot_index]);
|
|
||||||
pivot_index = last_index;
|
|
||||||
|
|
||||||
// 4^, 8, 7, 5, 2, 3, 6
|
|
||||||
if (less_than(array[start_index], array[pivot_index], user_context))
|
|
||||||
partition_index++;
|
|
||||||
start_index++;
|
|
||||||
|
|
||||||
// 4, |8, 7, 5^, 2, 3, 6*
|
|
||||||
// 4, 5, |7, 8, 2^, 3, 6*
|
|
||||||
// 4, 5, 2, |8, 7, ^3, 6*
|
|
||||||
// 4, 5, 2, 3, |7, 8, ^6*
|
|
||||||
for (DN_USize index = start_index; index < last_index; index++) {
|
|
||||||
if (less_than(array[index], array[pivot_index], user_context)) {
|
|
||||||
DN_Swap(array[partition_index], array[index]);
|
|
||||||
partition_index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move pivot to right of partition
|
|
||||||
// 4, 5, 2, 3, |6, 8, ^7*
|
|
||||||
DN_Swap(array[partition_index], array[pivot_index]);
|
|
||||||
DN_QSort(array, partition_index, user_context, less_than);
|
|
||||||
|
|
||||||
// Skip the value at partion index since that is guaranteed to be sorted.
|
|
||||||
// 4, 5, 2, 3, (x), 8, 7
|
|
||||||
DN_USize one_after_partition_index = partition_index + 1;
|
|
||||||
DN_QSort(array + one_after_partition_index, (array_size - one_after_partition_index), user_context, less_than);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // !defined(DN_HELPERS_H)
|
#endif // !defined(DN_HELPERS_H)
|
||||||
|
|||||||
+41
-7
@@ -42,15 +42,40 @@ DN_NETRequestHandle DN_NET_HandleFromRequest(DN_NETRequest *request)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DN_NET_EndFinishedRequest_(DN_NETRequest *request)
|
bool DN_NET_ResponseHasFailed(DN_NETResponse const* resp)
|
||||||
{
|
{
|
||||||
// NOTE: Deallocate the memory used in the request and reset the string builder
|
bool result = false;
|
||||||
DN_ArenaTempEnd(&request->start_response_arena, DN_ArenaReset_Yes);
|
if (resp->type == DN_NETRequestType_HTTP)
|
||||||
// NOTE: Check that the request is completely detached
|
result = resp->state == DN_NETResponseState_Error || resp->http_status >= 400;
|
||||||
DN_Assert(request->next == nullptr);
|
else
|
||||||
|
result = resp->state == DN_NETResponseState_Error;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DN_NET_BaseInit_(DN_NETCore *net, char *base, DN_U64 base_size)
|
DN_Str8 DN_NET_Str8DiagnosticFromResponse(DN_NETResponse const* resp, DN_Arena *arena)
|
||||||
|
{
|
||||||
|
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||||
|
DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
|
||||||
|
bool resp_failed = DN_NET_ResponseHasFailed(resp);
|
||||||
|
DN_Str8BuilderAppendF(&builder, "Request %s (%s", resp_failed ? "failed" : "succeeded", resp->type == DN_NETRequestType_HTTP ? "HTTP" : "WS");
|
||||||
|
if (resp->type == DN_NETRequestType_HTTP) {
|
||||||
|
if (resp->http_status)
|
||||||
|
DN_Str8BuilderAppendF(&builder, " %u", resp->http_status);
|
||||||
|
}
|
||||||
|
DN_Str8BuilderAppendF(&builder, ")");
|
||||||
|
if (resp->body.size || resp->error_str8.size) {
|
||||||
|
DN_Str8BuilderAppendRef(&builder, DN_Str8Lit(" with "));
|
||||||
|
if (resp->body.size)
|
||||||
|
DN_Str8BuilderAppendF(&builder, "%.*s", DN_Str8PrintFmt(resp->body));
|
||||||
|
if (resp->error_str8.size)
|
||||||
|
DN_Str8BuilderAppendF(&builder, "%s%.*s", resp->body.size ? ". " : "", DN_Str8PrintFmt(resp->error_str8));
|
||||||
|
}
|
||||||
|
DN_Str8 result = DN_Str8FromStr8BuilderArena(&builder, arena);
|
||||||
|
DN_TCScratchEnd(&scratch);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DN_NET_BaseInit(DN_NETCore *net, char *base, DN_U64 base_size)
|
||||||
{
|
{
|
||||||
net->base = base;
|
net->base = base;
|
||||||
net->base_size = base_size;
|
net->base_size = base_size;
|
||||||
@@ -59,7 +84,7 @@ void DN_NET_BaseInit_(DN_NETCore *net, char *base, DN_U64 base_size)
|
|||||||
net->completion_sem = DN_OS_SemaphoreInit(0);
|
net->completion_sem = DN_OS_SemaphoreInit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_NETRequestHandle DN_NET_SetupRequest_(DN_NETRequest *request, DN_Str8 url, DN_Str8 method, DN_NETDoHTTPArgs const *args, DN_NETRequestType type)
|
DN_NETRequestHandle DN_NET_SetupRequest(DN_NETRequest *request, DN_Str8 url, DN_Str8 method, DN_NETDoHTTPArgs const *args, DN_NETRequestType type)
|
||||||
{
|
{
|
||||||
// NOTE: Setup request
|
// NOTE: Setup request
|
||||||
DN_Assert(request);
|
DN_Assert(request);
|
||||||
@@ -94,5 +119,14 @@ DN_NETRequestHandle DN_NET_SetupRequest_(DN_NETRequest *request, DN_Str8 url, DN
|
|||||||
|
|
||||||
DN_NETRequestHandle result = DN_NET_HandleFromRequest(request);
|
DN_NETRequestHandle result = DN_NET_HandleFromRequest(request);
|
||||||
request->response.request = result;
|
request->response.request = result;
|
||||||
|
request->response.type = request->type;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DN_NET_EndFinishedRequest(DN_NETRequest *request)
|
||||||
|
{
|
||||||
|
// NOTE: Deallocate the memory used in the request and reset the string builder
|
||||||
|
DN_ArenaTempEnd(&request->start_response_arena, DN_ArenaReset_Yes);
|
||||||
|
// NOTE: Check that the request is completely detached
|
||||||
|
DN_Assert(request->next == nullptr);
|
||||||
|
}
|
||||||
|
|||||||
+10
-7
@@ -51,7 +51,7 @@ struct DN_NETDoHTTPArgs
|
|||||||
DN_U16 headers_size;
|
DN_U16 headers_size;
|
||||||
|
|
||||||
// NOTE: HTTP args only
|
// NOTE: HTTP args only
|
||||||
DN_Str8 payload;
|
DN_Str8 payload;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DN_NETRequestHandle
|
struct DN_NETRequestHandle
|
||||||
@@ -63,6 +63,7 @@ struct DN_NETRequestHandle
|
|||||||
struct DN_NETResponse
|
struct DN_NETResponse
|
||||||
{
|
{
|
||||||
// NOTE: Common to WS and HTTP responses
|
// NOTE: Common to WS and HTTP responses
|
||||||
|
DN_NETRequestType type;
|
||||||
DN_NETResponseState state;
|
DN_NETResponseState state;
|
||||||
DN_NETRequestHandle request;
|
DN_NETRequestHandle request;
|
||||||
DN_Str8 error_str8;
|
DN_Str8 error_str8;
|
||||||
@@ -119,13 +120,15 @@ struct DN_NETCore
|
|||||||
DN_NETInterface api;
|
DN_NETInterface api;
|
||||||
};
|
};
|
||||||
|
|
||||||
DN_Str8 DN_NET_Str8FromResponseState(DN_NETResponseState state);
|
DN_Str8 DN_NET_Str8FromResponseState (DN_NETResponseState state);
|
||||||
DN_NETRequest * DN_NET_RequestFromHandle (DN_NETRequestHandle handle);
|
DN_NETRequest * DN_NET_RequestFromHandle (DN_NETRequestHandle handle);
|
||||||
DN_NETRequestHandle DN_NET_HandleFromRequest (DN_NETRequest *request);
|
DN_NETRequestHandle DN_NET_HandleFromRequest (DN_NETRequest *request);
|
||||||
|
bool DN_NET_ResponseHasFailed (DN_NETResponse const* resp);
|
||||||
|
DN_Str8 DN_NET_Str8DiagnosticFromResponse(DN_NETResponse const* resp, DN_Arena *arena);
|
||||||
|
|
||||||
// NOTE: Internal functions for different networking implementations to use
|
// NOTE: Internal functions for different networking implementations to use
|
||||||
void DN_NET_BaseInit_ (DN_NETCore *net, char *base, DN_U64 base_size);
|
void DN_NET_BaseInit (DN_NETCore *net, char *base, DN_U64 base_size);
|
||||||
DN_NETRequestHandle DN_NET_SetupRequest_ (DN_NETRequest *request, DN_Str8 url, DN_Str8 method, DN_NETDoHTTPArgs const *args, DN_NETRequestType type);
|
DN_NETRequestHandle DN_NET_SetupRequest (DN_NETRequest *request, DN_Str8 url, DN_Str8 method, DN_NETDoHTTPArgs const *args, DN_NETRequestType type);
|
||||||
void DN_NET_EndFinishedRequest_ (DN_NETRequest *request);
|
void DN_NET_EndFinishedRequest (DN_NETRequest *request);
|
||||||
|
|
||||||
#endif // DN_NET_H
|
#endif // DN_NET_H
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
|||||||
DN_OS_ThreadSetNameFmt("%.*s", DN_Str8PrintFmt(curl->thread.name));
|
DN_OS_ThreadSetNameFmt("%.*s", DN_Str8PrintFmt(curl->thread.name));
|
||||||
|
|
||||||
while (!curl->kill_thread) {
|
while (!curl->kill_thread) {
|
||||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch tmem = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
|
|
||||||
// NOTE: Handle events sitting in the ring queue
|
// NOTE: Handle events sitting in the ring queue
|
||||||
for (bool dequeue_ring = true; dequeue_ring;) {
|
for (bool dequeue_ring = true; dequeue_ring;) {
|
||||||
@@ -159,7 +159,7 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
|||||||
// NOTE: End the temp memory storing the WS data we just read and the user returned to us
|
// NOTE: End the temp memory storing the WS data we just read and the user returned to us
|
||||||
// (we got their receipt back). Then restart the temp memory scope for the next websocket
|
// (we got their receipt back). Then restart the temp memory scope for the next websocket
|
||||||
// payload
|
// payload
|
||||||
DN_NET_EndFinishedRequest_(req);
|
DN_NET_EndFinishedRequest(req);
|
||||||
req->start_response_arena = DN_ArenaTempBeginFromArena(&req->arena);
|
req->start_response_arena = DN_ArenaTempBeginFromArena(&req->arena);
|
||||||
curl_req->str8_builder = DN_Str8BuilderFromArena(&req->start_response_arena);
|
curl_req->str8_builder = DN_Str8BuilderFromArena(&req->start_response_arena);
|
||||||
|
|
||||||
@@ -175,12 +175,15 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
|||||||
DN_NETRequest *request = DN_Cast(DN_NETRequest *) event.request.handle;
|
DN_NETRequest *request = DN_Cast(DN_NETRequest *) event.request.handle;
|
||||||
|
|
||||||
// NOTE: Release resources
|
// NOTE: Release resources
|
||||||
DN_NET_EndFinishedRequest_(request);
|
DN_NET_EndFinishedRequest(request);
|
||||||
DN_OS_SemaphoreDeinit(&request->completion_sem);
|
DN_OS_SemaphoreDeinit(&request->completion_sem);
|
||||||
|
|
||||||
curl_multi_remove_handle(curl->thread_curlm, curl_req->handle);
|
curl_multi_remove_handle(curl->thread_curlm, curl_req->handle);
|
||||||
curl_easy_reset(curl_req->handle);
|
|
||||||
curl_slist_free_all(curl_req->slist);
|
curl_slist_free_all(curl_req->slist);
|
||||||
|
curl_easy_reset(curl_req->handle);
|
||||||
|
CURL *copy = curl_req->handle;
|
||||||
|
*curl_req = {};
|
||||||
|
curl_req->handle = copy;
|
||||||
|
|
||||||
// NOTE: Zero the struct preserving just the data we need to retain
|
// NOTE: Zero the struct preserving just the data we need to retain
|
||||||
DN_NETRequest resetter = {};
|
DN_NETRequest resetter = {};
|
||||||
@@ -230,13 +233,13 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
|||||||
req->response.state = DN_NETResponseState_WSOpen;
|
req->response.state = DN_NETResponseState_WSOpen;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
req->response.error_str8 = DN_Str8FromFmtArena(&req->arena, "Failed to get HTTP response status (CURL %d): %s", msg->data.result, curl_easy_strerror(get_result));
|
req->response.error_str8 = DN_Str8FromFmtArena(&req->start_response_arena, "Failed to get HTTP response status (CURL %d): %s", msg->data.result, curl_easy_strerror(get_result));
|
||||||
req->response.state = DN_NETResponseState_Error;
|
req->response.state = DN_NETResponseState_Error;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DN_USize curl_extended_error_size = DN_CStr8Size(curl_req->error);
|
DN_USize curl_extended_error_size = DN_CStr8Size(curl_req->error);
|
||||||
req->response.state = DN_NETResponseState_Error;
|
req->response.state = DN_NETResponseState_Error;
|
||||||
req->response.error_str8 = DN_Str8FromFmtArena(&req->arena,
|
req->response.error_str8 = DN_Str8FromFmtArena(&req->start_response_arena,
|
||||||
"HTTP request '%.*s' failed (CURL %d): %s%s%s%s",
|
"HTTP request '%.*s' failed (CURL %d): %s%s%s%s",
|
||||||
DN_Str8PrintFmt(req->url),
|
DN_Str8PrintFmt(req->url),
|
||||||
msg->data.result,
|
msg->data.result,
|
||||||
@@ -400,7 +403,7 @@ DN_NETInterface DN_NET_CurlInterface()
|
|||||||
|
|
||||||
void DN_NET_CurlInit(DN_NETCore *net, char *base, DN_U64 base_size)
|
void DN_NET_CurlInit(DN_NETCore *net, char *base, DN_U64 base_size)
|
||||||
{
|
{
|
||||||
DN_NET_BaseInit_(net, base, base_size);
|
DN_NET_BaseInit(net, base, base_size);
|
||||||
DN_NETCurlCore *curl = DN_ArenaNew(&net->arena, DN_NETCurlCore, DN_ZMem_Yes);
|
DN_NETCurlCore *curl = DN_ArenaNew(&net->arena, DN_NETCurlCore, DN_ZMem_Yes);
|
||||||
net->context = curl;
|
net->context = curl;
|
||||||
net->api = DN_NET_CurlInterface();
|
net->api = DN_NET_CurlInterface();
|
||||||
@@ -458,8 +461,7 @@ static DN_NETRequestHandle DN_NET_CurlDoRequest_(DN_NETCore *net, DN_Str8 url, D
|
|||||||
// NOTE: Setup the request
|
// NOTE: Setup the request
|
||||||
DN_NETCurlRequest *curl_req = DN_NET_CurlRequestFromRequest_(req);
|
DN_NETCurlRequest *curl_req = DN_NET_CurlRequestFromRequest_(req);
|
||||||
{
|
{
|
||||||
result = DN_NET_SetupRequest_(req, url, method, args, type);
|
result = DN_NET_SetupRequest(req, url, method, args, type);
|
||||||
req->response.request = result;
|
|
||||||
req->context[1] = DN_Cast(DN_UPtr) net;
|
req->context[1] = DN_Cast(DN_UPtr) net;
|
||||||
curl_req->str8_builder = DN_Str8BuilderFromArena(&req->start_response_arena);
|
curl_req->str8_builder = DN_Str8BuilderFromArena(&req->start_response_arena);
|
||||||
}
|
}
|
||||||
@@ -480,8 +482,10 @@ static DN_NETRequestHandle DN_NET_CurlDoRequest_(DN_NETCore *net, DN_Str8 url, D
|
|||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, req);
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, req);
|
||||||
|
|
||||||
// NOTE: Assign HTTP headers
|
// NOTE: Assign HTTP headers
|
||||||
for (DN_ForItSize(it, DN_Str8, req->args.headers, req->args.headers_size))
|
for (DN_ForItSize(it, DN_Str8, req->args.headers, req->args.headers_size)) {
|
||||||
|
DN_Assert(it.data->data[it.data->size] == 0);
|
||||||
curl_req->slist = curl_slist_append(curl_req->slist, it.data->data);
|
curl_req->slist = curl_slist_append(curl_req->slist, it.data->data);
|
||||||
|
}
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_req->slist);
|
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_req->slist);
|
||||||
|
|
||||||
// NOTE: Setup handle for protocol
|
// NOTE: Setup handle for protocol
|
||||||
@@ -593,7 +597,7 @@ static DN_NETResponse DN_NET_CurlHandleFinishedRequest_(DN_NETCurlCore *curl, DN
|
|||||||
DN_NETResponse result = req->response;
|
DN_NETResponse result = req->response;
|
||||||
DN_NETCurlRequest *curl_req = DN_NET_CurlRequestFromRequest_(req);
|
DN_NETCurlRequest *curl_req = DN_NET_CurlRequestFromRequest_(req);
|
||||||
{
|
{
|
||||||
result.body = DN_Str8BuilderBuild(&curl_req->str8_builder, arena);
|
result.body = DN_Str8FromStr8BuilderArena(&curl_req->str8_builder, arena);
|
||||||
if (result.error_str8.size)
|
if (result.error_str8.size)
|
||||||
result.error_str8 = DN_Str8FromStr8Arena(result.error_str8, arena);
|
result.error_str8 = DN_Str8FromStr8Arena(result.error_str8, arena);
|
||||||
}
|
}
|
||||||
|
|||||||
+94
-34
@@ -365,6 +365,66 @@ static DN_UTCore DN_TST_Base()
|
|||||||
DN_UT_Assert(&result, mutex.ticket == ticket_b + 1);
|
DN_UT_Assert(&result, mutex.ticket == ticket_b + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (DN_UT_Test(&result, "QSort String (Natural)")) {
|
||||||
|
DN_Str8 list[] = {
|
||||||
|
DN_Str8Lit("item10"),
|
||||||
|
DN_Str8Lit("item2"),
|
||||||
|
DN_Str8Lit("item1"),
|
||||||
|
DN_Str8Lit("item20"),
|
||||||
|
DN_Str8Lit("item12"),
|
||||||
|
DN_Str8Lit("Afile"),
|
||||||
|
DN_Str8Lit("file2"),
|
||||||
|
DN_Str8Lit("file10"),
|
||||||
|
DN_Str8Lit("file1"),
|
||||||
|
DN_Str8Lit("z_last"),
|
||||||
|
DN_Str8Lit("m_middle"),
|
||||||
|
DN_Str8Lit("a_first"),
|
||||||
|
DN_Str8Lit("version-1.2.10"),
|
||||||
|
DN_Str8Lit("version-1.2.2"),
|
||||||
|
DN_Str8Lit("version-1.10.0"),
|
||||||
|
};
|
||||||
|
|
||||||
|
DN_QSortStr8NaturalAsc(list, DN_ArrayCountU(list), DN_Str8EqCase_Sensitive);
|
||||||
|
|
||||||
|
DN_USize list_index = 0;
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("Afile")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("a_first")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("file1")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("file2")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("file10")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("item1")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("item2")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("item10")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("item12")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("item20")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("m_middle")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("version-1.2.2")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("version-1.2.10")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("version-1.10.0")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("z_last")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (DN_UT_Test(&result, "QSort String (Lexicographic)")) {
|
||||||
|
DN_Str8 list[] = {
|
||||||
|
DN_Str8Lit("z_last"),
|
||||||
|
DN_Str8Lit("m_middle"),
|
||||||
|
DN_Str8Lit("a_first"),
|
||||||
|
DN_Str8Lit("version-1.2.10"),
|
||||||
|
DN_Str8Lit("version-1.2.2"),
|
||||||
|
DN_Str8Lit("version-1.10.0"),
|
||||||
|
};
|
||||||
|
|
||||||
|
DN_QSortStr8LexicographicAsc(list, DN_ArrayCountU(list), DN_Str8EqCase_Insensitive);
|
||||||
|
|
||||||
|
DN_USize list_index = 0;
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("a_first")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("m_middle")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("version-1.10.0")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("version-1.2.10")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("version-1.2.2")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
DN_AssertF(DN_Str8Eq(list[list_index++], DN_Str8Lit("z_last")), "%.*s", DN_Str8PrintFmt(list[list_index-1]));
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: MSVC SAL complains that we are using Interlocked functionality on
|
// NOTE: MSVC SAL complains that we are using Interlocked functionality on
|
||||||
// variables it has detected as *not* being shared across threads. This is
|
// variables it has detected as *not* being shared across threads. This is
|
||||||
// fine, we're just running some basic results, so permit it.
|
// fine, we're just running some basic results, so permit it.
|
||||||
@@ -529,7 +589,7 @@ static DN_UTCore DN_TST_BaseArena()
|
|||||||
|
|
||||||
static DN_UTCore DN_TST_BaseBytesHex()
|
static DN_UTCore DN_TST_BaseBytesHex()
|
||||||
{
|
{
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_UTCore test = DN_UT_Init();
|
DN_UTCore test = DN_UT_Init();
|
||||||
DN_UT_LogF(&test, "Bytes <-> Hex\n");
|
DN_UT_LogF(&test, "Bytes <-> Hex\n");
|
||||||
{
|
{
|
||||||
@@ -935,7 +995,7 @@ static DN_UTCore DN_TST_BaseDSMap()
|
|||||||
DN_UTCore result = DN_UT_Init();
|
DN_UTCore result = DN_UT_Init();
|
||||||
DN_UT_LogF(&result, "DN_DSMap\n");
|
DN_UT_LogF(&result, "DN_DSMap\n");
|
||||||
{
|
{
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
{
|
{
|
||||||
DN_MemList mem = DN_MemListFromVMem(0, 0, DN_MemFlags_Nil);
|
DN_MemList mem = DN_MemListFromVMem(0, 0, DN_MemFlags_Nil);
|
||||||
DN_Arena arena = DN_ArenaFromMemList(&mem);
|
DN_Arena arena = DN_ArenaFromMemList(&mem);
|
||||||
@@ -1134,7 +1194,7 @@ static DN_UTCore DN_TST_BaseIArray()
|
|||||||
struct CustomArray
|
struct CustomArray
|
||||||
{
|
{
|
||||||
int *data;
|
int *data;
|
||||||
DN_USize size;
|
DN_USize count;
|
||||||
DN_USize max;
|
DN_USize max;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1145,24 +1205,24 @@ static DN_UTCore DN_TST_BaseIArray()
|
|||||||
|
|
||||||
for (DN_UT_Test(&result, "Make item")) {
|
for (DN_UT_Test(&result, "Make item")) {
|
||||||
int *item = DN_IArrayMake(&array, DN_ZMem_Yes);
|
int *item = DN_IArrayMake(&array, DN_ZMem_Yes);
|
||||||
DN_UT_Assert(&result, item && array.size == 1);
|
DN_UT_Assert(&result, item && array.count == 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DN_UTCore DN_TST_BaseCArray2()
|
static DN_UTCore DN_TST_BaseArray()
|
||||||
{
|
{
|
||||||
DN_UTCore result = DN_UT_Init();
|
DN_UTCore result = DN_UT_Init();
|
||||||
DN_UT_LogF(&result, "DN_CArray2\n");
|
DN_UT_LogF(&result, "DN_Array\n");
|
||||||
{
|
{
|
||||||
for (DN_UT_Test(&result, "Positive count, middle of array, stable erase")) {
|
for (DN_UT_Test(&result, "Positive count, middle of array, stable erase")) {
|
||||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
DN_USize size = 10;
|
DN_USize size = 10;
|
||||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 3, 2, DN_ArrayErase_Stable);
|
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 3, 2, DN_ArrayErase_Stable);
|
||||||
int expected[] = {0, 1, 2, 5, 6, 7, 8, 9};
|
int expected[] = {0, 1, 2, 5, 6, 7, 8, 9};
|
||||||
DN_UT_Assert(&result, erase.items_erased == 2);
|
DN_UT_Assert(&result, erase.items_erased == 2);
|
||||||
DN_UT_Assert(&result, erase.it_index == 3);
|
DN_UT_AssertF(&result, erase.it_index == 2, "erase.it_index=%zu", erase.it_index);
|
||||||
DN_UT_Assert(&result, size == 8);
|
DN_UT_Assert(&result, size == 8);
|
||||||
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
||||||
}
|
}
|
||||||
@@ -1170,10 +1230,10 @@ static DN_UTCore DN_TST_BaseCArray2()
|
|||||||
for (DN_UT_Test(&result, "Negative count, middle of array, stable erase")) {
|
for (DN_UT_Test(&result, "Negative count, middle of array, stable erase")) {
|
||||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
DN_USize size = 10;
|
DN_USize size = 10;
|
||||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Stable);
|
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Stable);
|
||||||
int expected[] = {0, 1, 2, 6, 7, 8, 9};
|
int expected[] = {0, 1, 2, 6, 7, 8, 9};
|
||||||
DN_UT_Assert(&result, erase.items_erased == 3);
|
DN_UT_Assert(&result, erase.items_erased == 3);
|
||||||
DN_UT_Assert(&result, erase.it_index == 3);
|
DN_UT_Assert(&result, erase.it_index == 2);
|
||||||
DN_UT_Assert(&result, size == 7);
|
DN_UT_Assert(&result, size == 7);
|
||||||
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
||||||
}
|
}
|
||||||
@@ -1181,10 +1241,10 @@ static DN_UTCore DN_TST_BaseCArray2()
|
|||||||
for (DN_UT_Test(&result, "count = -1, stable erase")) {
|
for (DN_UT_Test(&result, "count = -1, stable erase")) {
|
||||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
DN_USize size = 10;
|
DN_USize size = 10;
|
||||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -1, DN_ArrayErase_Stable);
|
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -1, DN_ArrayErase_Stable);
|
||||||
int expected[] = {0, 1, 2, 3, 4, 6, 7, 8, 9};
|
int expected[] = {0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||||
DN_UT_Assert(&result, erase.items_erased == 1);
|
DN_UT_Assert(&result, erase.items_erased == 1);
|
||||||
DN_UT_Assert(&result, erase.it_index == 5);
|
DN_UT_Assert(&result, erase.it_index == 4);
|
||||||
DN_UT_Assert(&result, size == 9);
|
DN_UT_Assert(&result, size == 9);
|
||||||
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
||||||
}
|
}
|
||||||
@@ -1192,10 +1252,10 @@ static DN_UTCore DN_TST_BaseCArray2()
|
|||||||
for (DN_UT_Test(&result, "Positive count, unstable erase")) {
|
for (DN_UT_Test(&result, "Positive count, unstable erase")) {
|
||||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
DN_USize size = 10;
|
DN_USize size = 10;
|
||||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 3, 2, DN_ArrayErase_Unstable);
|
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 3, 2, DN_ArrayErase_Unstable);
|
||||||
int expected[] = {0, 1, 2, 8, 9, 5, 6, 7};
|
int expected[] = {0, 1, 2, 8, 9, 5, 6, 7};
|
||||||
DN_UT_Assert(&result, erase.items_erased == 2);
|
DN_UT_Assert(&result, erase.items_erased == 2);
|
||||||
DN_UT_Assert(&result, erase.it_index == 3);
|
DN_UT_Assert(&result, erase.it_index == 2);
|
||||||
DN_UT_Assert(&result, size == 8);
|
DN_UT_Assert(&result, size == 8);
|
||||||
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
||||||
}
|
}
|
||||||
@@ -1203,10 +1263,10 @@ static DN_UTCore DN_TST_BaseCArray2()
|
|||||||
for (DN_UT_Test(&result, "Negative count, unstable erase")) {
|
for (DN_UT_Test(&result, "Negative count, unstable erase")) {
|
||||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
DN_USize size = 10;
|
DN_USize size = 10;
|
||||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Unstable);
|
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, -3, DN_ArrayErase_Unstable);
|
||||||
int expected[] = {0, 1, 2, 7, 8, 9, 6};
|
int expected[] = {0, 1, 2, 7, 8, 9, 6};
|
||||||
DN_UT_Assert(&result, erase.items_erased == 3);
|
DN_UT_Assert(&result, erase.items_erased == 3);
|
||||||
DN_UT_Assert(&result, erase.it_index == 3);
|
DN_UT_Assert(&result, erase.it_index == 2);
|
||||||
DN_UT_Assert(&result, size == 7);
|
DN_UT_Assert(&result, size == 7);
|
||||||
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
||||||
}
|
}
|
||||||
@@ -1214,7 +1274,7 @@ static DN_UTCore DN_TST_BaseCArray2()
|
|||||||
for (DN_UT_Test(&result, "Edge case - begin_index at start, negative count")) {
|
for (DN_UT_Test(&result, "Edge case - begin_index at start, negative count")) {
|
||||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
DN_USize size = 10;
|
DN_USize size = 10;
|
||||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 0, -2, DN_ArrayErase_Stable);
|
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 0, -2, DN_ArrayErase_Stable);
|
||||||
int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
|
int expected[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
DN_UT_Assert(&result, erase.items_erased == 1);
|
DN_UT_Assert(&result, erase.items_erased == 1);
|
||||||
DN_UT_Assert(&result, erase.it_index == 0);
|
DN_UT_Assert(&result, erase.it_index == 0);
|
||||||
@@ -1225,10 +1285,10 @@ static DN_UTCore DN_TST_BaseCArray2()
|
|||||||
for (DN_UT_Test(&result, "Edge case - begin_index at end, positive count")) {
|
for (DN_UT_Test(&result, "Edge case - begin_index at end, positive count")) {
|
||||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
DN_USize size = 10;
|
DN_USize size = 10;
|
||||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 9, 2, DN_ArrayErase_Stable);
|
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 9, 2, DN_ArrayErase_Stable);
|
||||||
int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
|
int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
|
||||||
DN_UT_Assert(&result, erase.items_erased == 1);
|
DN_UT_Assert(&result, erase.items_erased == 1);
|
||||||
DN_UT_Assert(&result, erase.it_index == 9);
|
DN_UT_Assert(&result, erase.it_index == 8);
|
||||||
DN_UT_Assert(&result, size == 9);
|
DN_UT_Assert(&result, size == 9);
|
||||||
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
||||||
}
|
}
|
||||||
@@ -1236,7 +1296,7 @@ static DN_UTCore DN_TST_BaseCArray2()
|
|||||||
for (DN_UT_Test(&result, "Invalid input - count = 0")) {
|
for (DN_UT_Test(&result, "Invalid input - count = 0")) {
|
||||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
DN_USize size = 10;
|
DN_USize size = 10;
|
||||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 5, 0, DN_ArrayErase_Stable);
|
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, 0, DN_ArrayErase_Stable);
|
||||||
int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
DN_UT_Assert(&result, erase.items_erased == 0);
|
DN_UT_Assert(&result, erase.items_erased == 0);
|
||||||
DN_UT_Assert(&result, erase.it_index == 0);
|
DN_UT_Assert(&result, erase.it_index == 0);
|
||||||
@@ -1246,7 +1306,7 @@ static DN_UTCore DN_TST_BaseCArray2()
|
|||||||
|
|
||||||
for (DN_UT_Test(&result, "Invalid input - null data")) {
|
for (DN_UT_Test(&result, "Invalid input - null data")) {
|
||||||
DN_USize size = 10;
|
DN_USize size = 10;
|
||||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(nullptr, &size, sizeof(int), 5, 2, DN_ArrayErase_Stable);
|
DN_ArrayEraseResult erase = DN_ArrayEraseRange(nullptr, &size, sizeof(int), 5, 2, DN_ArrayErase_Stable);
|
||||||
DN_UT_Assert(&result, erase.items_erased == 0);
|
DN_UT_Assert(&result, erase.items_erased == 0);
|
||||||
DN_UT_Assert(&result, erase.it_index == 0);
|
DN_UT_Assert(&result, erase.it_index == 0);
|
||||||
DN_UT_Assert(&result, size == 10);
|
DN_UT_Assert(&result, size == 10);
|
||||||
@@ -1254,7 +1314,7 @@ static DN_UTCore DN_TST_BaseCArray2()
|
|||||||
|
|
||||||
for (DN_UT_Test(&result, "Invalid input - null size")) {
|
for (DN_UT_Test(&result, "Invalid input - null size")) {
|
||||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, NULL, sizeof(arr[0]), 5, 2, DN_ArrayErase_Stable);
|
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, NULL, sizeof(arr[0]), 5, 2, DN_ArrayErase_Stable);
|
||||||
DN_UT_Assert(&result, erase.items_erased == 0);
|
DN_UT_Assert(&result, erase.items_erased == 0);
|
||||||
DN_UT_Assert(&result, erase.it_index == 0);
|
DN_UT_Assert(&result, erase.it_index == 0);
|
||||||
}
|
}
|
||||||
@@ -1262,7 +1322,7 @@ static DN_UTCore DN_TST_BaseCArray2()
|
|||||||
for (DN_UT_Test(&result, "Invalid input - empty array")) {
|
for (DN_UT_Test(&result, "Invalid input - empty array")) {
|
||||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
DN_USize size = 0;
|
DN_USize size = 0;
|
||||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 5, 2, DN_ArrayErase_Stable);
|
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 5, 2, DN_ArrayErase_Stable);
|
||||||
DN_UT_Assert(&result, erase.items_erased == 0);
|
DN_UT_Assert(&result, erase.items_erased == 0);
|
||||||
DN_UT_Assert(&result, erase.it_index == 0);
|
DN_UT_Assert(&result, erase.it_index == 0);
|
||||||
DN_UT_Assert(&result, size == 0);
|
DN_UT_Assert(&result, size == 0);
|
||||||
@@ -1271,10 +1331,10 @@ static DN_UTCore DN_TST_BaseCArray2()
|
|||||||
for (DN_UT_Test(&result, "Out-of-bounds begin_index")) {
|
for (DN_UT_Test(&result, "Out-of-bounds begin_index")) {
|
||||||
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
DN_USize size = 10;
|
DN_USize size = 10;
|
||||||
DN_ArrayEraseResult erase = DN_CArrayEraseRange(arr, &size, sizeof(arr[0]), 15, 2, DN_ArrayErase_Stable);
|
DN_ArrayEraseResult erase = DN_ArrayEraseRange(arr, &size, sizeof(arr[0]), 15, 2, DN_ArrayErase_Stable);
|
||||||
int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
int expected[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
DN_UT_Assert(&result, erase.items_erased == 0);
|
DN_UT_Assert(&result, erase.items_erased == 0);
|
||||||
DN_UT_Assert(&result, erase.it_index == 10);
|
DN_UT_Assert(&result, erase.it_index == 9);
|
||||||
DN_UT_Assert(&result, size == 10);
|
DN_UT_Assert(&result, size == 10);
|
||||||
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
DN_UT_Assert(&result, DN_Memcmp(arr, expected, size * sizeof(arr[0])) == 0);
|
||||||
}
|
}
|
||||||
@@ -1632,7 +1692,7 @@ DN_Str8 const DN_UT_HASH_STRING_[] =
|
|||||||
|
|
||||||
void DN_TST_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input)
|
void DN_TST_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input)
|
||||||
{
|
{
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str8 input_hex = DN_HexFromPtrBytesArena(input.data, input.size, &scratch.arena, DN_TrimLeadingZero_No);
|
DN_Str8 input_hex = DN_HexFromPtrBytesArena(input.data, input.size, &scratch.arena, DN_TrimLeadingZero_No);
|
||||||
|
|
||||||
switch (hash_type) {
|
switch (hash_type) {
|
||||||
@@ -1860,7 +1920,7 @@ static DN_UTCore DN_TST_OS()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (DN_UT_Test(&result, "Query executable directory")) {
|
for (DN_UT_Test(&result, "Query executable directory")) {
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str8 os_result = DN_OS_EXEDir(&scratch.arena);
|
DN_Str8 os_result = DN_OS_EXEDir(&scratch.arena);
|
||||||
DN_UT_Assert(&result, os_result.size);
|
DN_UT_Assert(&result, os_result.size);
|
||||||
DN_UT_AssertF(&result, DN_OS_PathIsDir(os_result), "result(%zu): %.*s", os_result.size, DN_Str8PrintFmt(os_result));
|
DN_UT_AssertF(&result, DN_OS_PathIsDir(os_result), "result(%zu): %.*s", os_result.size, DN_Str8PrintFmt(os_result));
|
||||||
@@ -1911,7 +1971,7 @@ static DN_UTCore DN_TST_OS()
|
|||||||
DN_UT_Assert(&result, DN_OS_PathIsFile(SRC_FILE));
|
DN_UT_Assert(&result, DN_OS_PathIsFile(SRC_FILE));
|
||||||
|
|
||||||
// NOTE: Read step
|
// NOTE: Read step
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str8 read_file = DN_OS_FileReadAllArena(&scratch.arena, SRC_FILE, nullptr);
|
DN_Str8 read_file = DN_OS_FileReadAllArena(&scratch.arena, SRC_FILE, nullptr);
|
||||||
DN_UT_AssertF(&result, read_file.size, "Failed to load file");
|
DN_UT_AssertF(&result, read_file.size, "Failed to load file");
|
||||||
DN_UT_AssertF(&result, read_file.size == 4, "File read wrong amount of bytes (%zu)", read_file.size);
|
DN_UT_AssertF(&result, read_file.size == 4, "File read wrong amount of bytes (%zu)", read_file.size);
|
||||||
@@ -2166,7 +2226,7 @@ static DN_UTCore DN_TST_BaseStrings()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (DN_UT_Test(&result, "Initialise with format string")) {
|
for (DN_UT_Test(&result, "Initialise with format string")) {
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str8 string = DN_Str8FromFmtArena(&scratch.arena, "%s", "AB");
|
DN_Str8 string = DN_Str8FromFmtArena(&scratch.arena, "%s", "AB");
|
||||||
DN_UT_AssertF(&result, string.size == 2, "size: %zu", string.size);
|
DN_UT_AssertF(&result, string.size == 2, "size: %zu", string.size);
|
||||||
DN_UT_AssertF(&result, string.data[0] == 'A', "string[0]: %c", string.data[0]);
|
DN_UT_AssertF(&result, string.data[0] == 'A', "string[0]: %c", string.data[0]);
|
||||||
@@ -2176,7 +2236,7 @@ static DN_UTCore DN_TST_BaseStrings()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (DN_UT_Test(&result, "Copy string")) {
|
for (DN_UT_Test(&result, "Copy string")) {
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str8 string = DN_Str8Lit("AB");
|
DN_Str8 string = DN_Str8Lit("AB");
|
||||||
DN_Str8 copy = DN_Str8FromStr8Arena(string, &scratch.arena);
|
DN_Str8 copy = DN_Str8FromStr8Arena(string, &scratch.arena);
|
||||||
DN_UT_AssertF(&result, copy.size == 2, "size: %zu", copy.size);
|
DN_UT_AssertF(&result, copy.size == 2, "size: %zu", copy.size);
|
||||||
@@ -2192,7 +2252,7 @@ static DN_UTCore DN_TST_BaseStrings()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (DN_UT_Test(&result, "Allocate string from arena")) {
|
for (DN_UT_Test(&result, "Allocate string from arena")) {
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str8 string = DN_Str8AllocArena(2, DN_ZMem_No, &scratch.arena);
|
DN_Str8 string = DN_Str8AllocArena(2, DN_ZMem_No, &scratch.arena);
|
||||||
DN_UT_AssertF(&result, string.size == 2, "size: %zu", string.size);
|
DN_UT_AssertF(&result, string.size == 2, "size: %zu", string.size);
|
||||||
DN_TCScratchEnd(&scratch);
|
DN_TCScratchEnd(&scratch);
|
||||||
@@ -2530,7 +2590,7 @@ static DN_UTCore DN_TST_BaseStrings()
|
|||||||
|
|
||||||
// NOTE: DN_Str8TruncMiddle (arena wrapper)
|
// NOTE: DN_Str8TruncMiddle (arena wrapper)
|
||||||
for (DN_UT_Test(&result, "TruncMiddle: Arena wrapper allocates and truncates correctly")) {
|
for (DN_UT_Test(&result, "TruncMiddle: Arena wrapper allocates and truncates correctly")) {
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str8 str = DN_Str8Lit("HelloBeautifulWorld");
|
DN_Str8 str = DN_Str8Lit("HelloBeautifulWorld");
|
||||||
DN_Str8 trunc = DN_Str8Lit("...");
|
DN_Str8 trunc = DN_Str8Lit("...");
|
||||||
DN_Str8TruncResult res = DN_Str8TruncMiddle(str, 5, trunc, &scratch.arena);
|
DN_Str8TruncResult res = DN_Str8TruncMiddle(str, 5, trunc, &scratch.arena);
|
||||||
@@ -2551,7 +2611,7 @@ static DN_UTCore DN_TST_Win()
|
|||||||
#if defined(DN_PLATFORM_WIN32)
|
#if defined(DN_PLATFORM_WIN32)
|
||||||
DN_UT_LogF(&result, "OS Win32\n");
|
DN_UT_LogF(&result, "OS Win32\n");
|
||||||
{
|
{
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str8 input8 = DN_Str8Lit("String");
|
DN_Str8 input8 = DN_Str8Lit("String");
|
||||||
DN_Str16 input16 = DN_Str16{(wchar_t *)(L"String"), sizeof(L"String") / sizeof(L"String"[0]) - 1};
|
DN_Str16 input16 = DN_Str16{(wchar_t *)(L"String"), sizeof(L"String") / sizeof(L"String"[0]) - 1};
|
||||||
|
|
||||||
@@ -2700,7 +2760,7 @@ DN_TSTResult DN_TST_RunSuite(DN_TSTPrint print)
|
|||||||
#endif
|
#endif
|
||||||
DN_TST_BaseDSMap(),
|
DN_TST_BaseDSMap(),
|
||||||
DN_TST_BaseIArray(),
|
DN_TST_BaseIArray(),
|
||||||
DN_TST_BaseCArray2(),
|
DN_TST_BaseArray(),
|
||||||
DN_TST_BaseVArray(),
|
DN_TST_BaseVArray(),
|
||||||
DN_TST_Keccak(),
|
DN_TST_Keccak(),
|
||||||
DN_TST_M4(),
|
DN_TST_M4(),
|
||||||
|
|||||||
@@ -35,8 +35,8 @@ DN_MSVC_WARNING_PUSH
|
|||||||
DN_MSVC_WARNING_DISABLE(6262) // Function uses '29804' bytes of stack. Consider moving some data to heap.
|
DN_MSVC_WARNING_DISABLE(6262) // Function uses '29804' bytes of stack. Consider moving some data to heap.
|
||||||
int main(int, char**)
|
int main(int, char**)
|
||||||
{
|
{
|
||||||
DN_Core dn = {};
|
DN_Core dn = {};
|
||||||
DN_Init(&dn, DN_InitFlags_LogAllFeatures | DN_InitFlags_OS | DN_InitFlags_ThreadContext, nullptr);
|
DN_Init(&dn, DN_InitFlags_LogAllFeatures | DN_InitFlags_OS | DN_InitFlags_ThreadContext, DN_TCInitArgsDefault());
|
||||||
DN_TST_RunSuite(DN_TSTPrint_Yes);
|
DN_TST_RunSuite(DN_TSTPrint_Yes);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+106
-57
@@ -67,6 +67,30 @@ DN_API DN_MemList DN_MemListFromVMem(DN_U64 reserve, DN_U64 commit, DN_MemFlags
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DN_API DN_Arena DN_ArenaFromHeap(DN_U64 size, DN_MemFlags flags)
|
||||||
|
{
|
||||||
|
DN_MemList mem = DN_MemListFromHeap(size, flags);
|
||||||
|
DN_Arena result = {};
|
||||||
|
result.flags |= DN_ArenaFlags_OwnsMemList;
|
||||||
|
result.mem = DN_MemListNewCopy(&mem, DN_MemList, &mem);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API DN_Arena DN_ArenaFromVMem(DN_U64 reserve, DN_U64 commit, DN_MemFlags flags)
|
||||||
|
{
|
||||||
|
DN_MemList mem = DN_MemListFromVMem(reserve, commit, flags);
|
||||||
|
DN_Arena result = {};
|
||||||
|
result.flags |= DN_ArenaFlags_OwnsMemList;
|
||||||
|
result.mem = DN_MemListNewCopy(&mem, DN_MemList, &mem);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API void DN_ArenaDeinit(DN_Arena *arena)
|
||||||
|
{
|
||||||
|
if (arena->flags & DN_ArenaFlags_OwnsMemList)
|
||||||
|
DN_MemListDeinit(arena->mem);
|
||||||
|
}
|
||||||
|
|
||||||
DN_API DN_Str8 DN_Str8FromHeapF(DN_FMT_ATTRIB char const *fmt, ...)
|
DN_API DN_Str8 DN_Str8FromHeapF(DN_FMT_ATTRIB char const *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
@@ -92,7 +116,7 @@ DN_API DN_Str8 DN_Str8FromHeap(DN_USize size, DN_ZMem z_mem)
|
|||||||
DN_API DN_Str8 DN_Str8PadNewLines(DN_Arena *arena, DN_Str8 src, DN_Str8 pad)
|
DN_API DN_Str8 DN_Str8PadNewLines(DN_Arena *arena, DN_Str8 src, DN_Str8 pad)
|
||||||
{
|
{
|
||||||
// TODO: Implement this without requiring TLS so it can go into base strings
|
// TODO: Implement this without requiring TLS so it can go into base strings
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
|
DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
|
||||||
DN_Str8BSplitResult split = DN_Str8BSplit(src, DN_Str8Lit("\n"));
|
DN_Str8BSplitResult split = DN_Str8BSplit(src, DN_Str8Lit("\n"));
|
||||||
while (split.lhs.size) {
|
while (split.lhs.size) {
|
||||||
@@ -102,7 +126,7 @@ DN_API DN_Str8 DN_Str8PadNewLines(DN_Arena *arena, DN_Str8 src, DN_Str8 pad)
|
|||||||
if (split.lhs.size)
|
if (split.lhs.size)
|
||||||
DN_Str8BuilderAppendRef(&builder, DN_Str8Lit("\n"));
|
DN_Str8BuilderAppendRef(&builder, DN_Str8Lit("\n"));
|
||||||
}
|
}
|
||||||
DN_Str8 result = DN_Str8BuilderBuild(&builder, arena);
|
DN_Str8 result = DN_Str8FromStr8BuilderArena(&builder, arena);
|
||||||
DN_TCScratchEnd(&scratch);
|
DN_TCScratchEnd(&scratch);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -135,7 +159,7 @@ DN_API void DN_OS_LogPrint(DN_LogTypeParam type, void *user_data, DN_CallSite ca
|
|||||||
// NOTE: Open log file for appending if requested
|
// NOTE: Open log file for appending if requested
|
||||||
DN_TicketMutex_Begin(&os->log_file_mutex);
|
DN_TicketMutex_Begin(&os->log_file_mutex);
|
||||||
if (os->log_to_file && !os->log_file.handle && !os->log_file.error) {
|
if (os->log_to_file && !os->log_file.handle && !os->log_file.error) {
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str8 exe_dir = DN_OS_EXEDir(&scratch.arena);
|
DN_Str8 exe_dir = DN_OS_EXEDir(&scratch.arena);
|
||||||
DN_Str8 log_path = DN_OS_PathF(&scratch.arena, "%.*s/dn.log", DN_Str8PrintFmt(exe_dir));
|
DN_Str8 log_path = DN_OS_PathF(&scratch.arena, "%.*s/dn.log", DN_Str8PrintFmt(exe_dir));
|
||||||
os->log_file = DN_OS_FileOpen(log_path, DN_OSFileOpen_CreateAlways, DN_OSFileAccess_AppendOnly, nullptr);
|
os->log_file = DN_OS_FileOpen(log_path, DN_OSFileOpen_CreateAlways, DN_OSFileAccess_AppendOnly, nullptr);
|
||||||
@@ -250,7 +274,7 @@ DN_API DN_Str8 DN_OS_EXEDir(DN_Arena *arena)
|
|||||||
DN_Str8 result = {};
|
DN_Str8 result = {};
|
||||||
if (!arena)
|
if (!arena)
|
||||||
return result;
|
return result;
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||||
DN_Str8 exe_path = DN_OS_EXEPath(&scratch.arena);
|
DN_Str8 exe_path = DN_OS_EXEPath(&scratch.arena);
|
||||||
DN_Str8 separators[] = {DN_Str8Lit("/"), DN_Str8Lit("\\")};
|
DN_Str8 separators[] = {DN_Str8Lit("/"), DN_Str8Lit("\\")};
|
||||||
DN_Str8BSplitResult split = DN_Str8BSplitLastArray(exe_path, separators, DN_ArrayCountU(separators));
|
DN_Str8BSplitResult split = DN_Str8BSplitLastArray(exe_path, separators, DN_ArrayCountU(separators));
|
||||||
@@ -421,7 +445,7 @@ DN_API DN_Str8 DN_OS_FileReadAll(DN_Allocator allocator, DN_Str8 path, DN_ErrSin
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!result.data) {
|
if (!result.data) {
|
||||||
DN_Str8x32 bytes_str = DN_ByteCountStr8x32(path_info.size);
|
DN_Str8x32 bytes_str = DN_Str8x32FromByteCountU64Auto(path_info.size);
|
||||||
DN_ErrSinkAppendF(err, 1 /*err_code*/, "Failed to allocate %.*s for reading file '%.*s'", DN_Str8PrintFmt(bytes_str), DN_Str8PrintFmt(path));
|
DN_ErrSinkAppendF(err, 1 /*err_code*/, "Failed to allocate %.*s for reading file '%.*s'", DN_Str8PrintFmt(bytes_str), DN_Str8PrintFmt(path));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -475,7 +499,7 @@ DN_API bool DN_OS_FileWriteAll(DN_Str8 path, DN_Str8 buffer, DN_ErrSink *error)
|
|||||||
|
|
||||||
DN_API bool DN_OS_FileWriteAllFV(DN_Str8 file_path, DN_ErrSink *error, DN_FMT_ATTRIB char const *fmt, va_list args)
|
DN_API bool DN_OS_FileWriteAllFV(DN_Str8 file_path, DN_ErrSink *error, DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||||
{
|
{
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str8 buffer = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
DN_Str8 buffer = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
||||||
bool result = DN_OS_FileWriteAll(file_path, buffer, error);
|
bool result = DN_OS_FileWriteAll(file_path, buffer, error);
|
||||||
DN_TCScratchEnd(&scratch);
|
DN_TCScratchEnd(&scratch);
|
||||||
@@ -493,7 +517,7 @@ DN_API bool DN_OS_FileWriteAllF(DN_Str8 file_path, DN_ErrSink *error, DN_FMT_ATT
|
|||||||
|
|
||||||
DN_API bool DN_OS_FileWriteAllSafe(DN_Str8 path, DN_Str8 buffer, DN_ErrSink *error)
|
DN_API bool DN_OS_FileWriteAllSafe(DN_Str8 path, DN_Str8 buffer, DN_ErrSink *error)
|
||||||
{
|
{
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str8 tmp_path = DN_Str8FromFmtArena(&scratch.arena, "%.*s.tmp", DN_Str8PrintFmt(path));
|
DN_Str8 tmp_path = DN_Str8FromFmtArena(&scratch.arena, "%.*s.tmp", DN_Str8PrintFmt(path));
|
||||||
if (!DN_OS_FileWriteAll(tmp_path, buffer, error)) {
|
if (!DN_OS_FileWriteAll(tmp_path, buffer, error)) {
|
||||||
DN_TCScratchEnd(&scratch);
|
DN_TCScratchEnd(&scratch);
|
||||||
@@ -513,7 +537,7 @@ DN_API bool DN_OS_FileWriteAllSafe(DN_Str8 path, DN_Str8 buffer, DN_ErrSink *err
|
|||||||
|
|
||||||
DN_API bool DN_OS_FileWriteAllSafeFV(DN_Str8 path, DN_ErrSink *error, DN_FMT_ATTRIB char const *fmt, va_list args)
|
DN_API bool DN_OS_FileWriteAllSafeFV(DN_Str8 path, DN_ErrSink *error, DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||||
{
|
{
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str8 buffer = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
DN_Str8 buffer = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
||||||
bool result = DN_OS_FileWriteAllSafe(path, buffer, error);
|
bool result = DN_OS_FileWriteAllSafe(path, buffer, error);
|
||||||
DN_TCScratchEnd(&scratch);
|
DN_TCScratchEnd(&scratch);
|
||||||
@@ -630,7 +654,7 @@ DN_API DN_Str8 DN_OS_PathTo(DN_Arena *arena, DN_Str8 path, DN_Str8 path_separato
|
|||||||
|
|
||||||
DN_API DN_Str8 DN_OS_PathToF(DN_Arena *arena, DN_Str8 path_separator, DN_FMT_ATTRIB char const *fmt, ...)
|
DN_API DN_Str8 DN_OS_PathToF(DN_Arena *arena, DN_Str8 path_separator, DN_FMT_ATTRIB char const *fmt, ...)
|
||||||
{
|
{
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
||||||
@@ -648,7 +672,7 @@ DN_API DN_Str8 DN_OS_Path(DN_Arena *arena, DN_Str8 path)
|
|||||||
|
|
||||||
DN_API DN_Str8 DN_OS_PathF(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...)
|
DN_API DN_Str8 DN_OS_PathF(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...)
|
||||||
{
|
{
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
||||||
@@ -714,9 +738,8 @@ DN_API DN_OSExecResult DN_OS_ExecOrAbort(DN_Str8Slice cmd_line, DN_OSExecArgs *a
|
|||||||
// NOTE: DN_OSThread
|
// NOTE: DN_OSThread
|
||||||
static void DN_OS_ThreadExecute_(void *user_context)
|
static void DN_OS_ThreadExecute_(void *user_context)
|
||||||
{
|
{
|
||||||
DN_OSThread *thread = DN_Cast(DN_OSThread *) user_context;
|
DN_OSThread *thread = DN_Cast(DN_OSThread *) user_context;
|
||||||
DN_MemFuncs mem_funcs = DN_MemFuncsDefault();
|
DN_TCInitFromMemFuncs(&thread->context, thread->thread_id, DN_TCInitArgsDefault(), DN_MemFuncsDefault());
|
||||||
DN_TCInitFromMemFuncs(&thread->context, thread->thread_id, /*args=*/nullptr, mem_funcs);
|
|
||||||
DN_TCEquip(&thread->context);
|
DN_TCEquip(&thread->context);
|
||||||
if (thread->is_lane_set) {
|
if (thread->is_lane_set) {
|
||||||
DN_OS_TCThreadLaneEquip(thread->lane);
|
DN_OS_TCThreadLaneEquip(thread->lane);
|
||||||
@@ -833,7 +856,7 @@ DN_API DN_OSHttpResponse DN_OS_HttpRequest(DN_Arena *arena, DN_Str8 host, DN_Str
|
|||||||
{
|
{
|
||||||
// TODO(doyle): Revise the memory allocation and its lifetime
|
// TODO(doyle): Revise the memory allocation and its lifetime
|
||||||
DN_OSHttpResponse result = {};
|
DN_OSHttpResponse result = {};
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||||
result.scratch_arena = scratch.arena;
|
result.scratch_arena = scratch.arena;
|
||||||
|
|
||||||
DN_OS_HttpRequestAsync(&result, arena, host, path, secure, method, body, headers);
|
DN_OS_HttpRequestAsync(&result, arena, host, path, secure, method, body, headers);
|
||||||
@@ -1116,7 +1139,7 @@ T *DN_OS_VArrayInsertArray(DN_VArray<T> *array, DN_USize index, T const *items,
|
|||||||
if (!DN_OS_VArrayIsValid(array))
|
if (!DN_OS_VArrayIsValid(array))
|
||||||
return result;
|
return result;
|
||||||
if (DN_OS_VArrayReserve(array, array->size + count))
|
if (DN_OS_VArrayReserve(array, array->size + count))
|
||||||
result = DN_CArrayInsertArray(array->data, &array->size, array->max, index, items, count);
|
result = DN_ArrayInsertArray(array->data, &array->size, array->max, index, items, count);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1137,14 +1160,14 @@ T *DN_OS_VArrayInsert(DN_VArray<T> *array, DN_USize index, T const &item)
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
T *DN_OS_VArrayPopFront(DN_VArray<T> *array, DN_USize count)
|
T *DN_OS_VArrayPopFront(DN_VArray<T> *array, DN_USize count)
|
||||||
{
|
{
|
||||||
T *result = DN_Cast(T *)DN_CArrayPopFront(array->data, &array->size, sizeof(T), count);
|
T *result = DN_Cast(T *)DN_ArrayPopFront(array->data, &array->size, sizeof(T), count);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T *DN_OS_VArrayPopBack(DN_VArray<T> *array, DN_USize count)
|
T *DN_OS_VArrayPopBack(DN_VArray<T> *array, DN_USize count)
|
||||||
{
|
{
|
||||||
T *result = DN_Cast(T *)DN_CArrayPopBack(array->data, &array->size, sizeof(T), count);
|
T *result = DN_Cast(T *)DN_ArrayPopBack(array->data, &array->size, sizeof(T), count);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1154,7 +1177,7 @@ DN_ArrayEraseResult DN_OS_VArrayEraseRange(DN_VArray<T> *array, DN_USize begin_i
|
|||||||
DN_ArrayEraseResult result = {};
|
DN_ArrayEraseResult result = {};
|
||||||
if (!DN_OS_VArrayIsValid(array))
|
if (!DN_OS_VArrayIsValid(array))
|
||||||
return result;
|
return result;
|
||||||
result = DN_CArrayEraseRange(array->data, &array->size, sizeof(T), begin_index, count, erase);
|
result = DN_ArrayEraseRange(array->data, &array->size, sizeof(T), begin_index, count, erase);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1183,12 +1206,11 @@ bool DN_OS_VArrayReserve(DN_VArray<T> *array, DN_USize count)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Stack Trace
|
DN_API DN_StackTrace DN_StackTraceFromAllocator(DN_Allocator allocator, DN_U16 limit)
|
||||||
DN_API DN_StackTraceWalkResult DN_StackTraceWalk(DN_Arena *arena, DN_U16 limit)
|
|
||||||
{
|
{
|
||||||
DN_StackTraceWalkResult result = {};
|
DN_StackTrace result = {};
|
||||||
#if defined(DN_OS_WIN32)
|
#if defined(DN_OS_WIN32)
|
||||||
if (!arena)
|
if (!allocator.context)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
static DN_TicketMutex mutex = {};
|
static DN_TicketMutex mutex = {};
|
||||||
@@ -1202,7 +1224,7 @@ DN_API DN_StackTraceWalkResult DN_StackTraceWalk(DN_Arena *arena, DN_U16 limit)
|
|||||||
w32->sym_initialised = true;
|
w32->sym_initialised = true;
|
||||||
SymSetOptions(SYMOPT_LOAD_LINES);
|
SymSetOptions(SYMOPT_LOAD_LINES);
|
||||||
if (!SymInitialize(result.process, nullptr /*UserSearchPath*/, true /*fInvadeProcess*/)) {
|
if (!SymInitialize(result.process, nullptr /*UserSearchPath*/, true /*fInvadeProcess*/)) {
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
|
DN_TCScratch scratch = DN_TCScratchBeginAllocator(&allocator, 1);
|
||||||
DN_OSW32Error error = DN_OS_W32LastError(&scratch.arena);
|
DN_OSW32Error error = DN_OS_W32LastError(&scratch.arena);
|
||||||
DN_LogErrorF("SymInitialize failed, stack trace can not be generated (%lu): %.*s\n", error.code, DN_Str8PrintFmt(error.msg));
|
DN_LogErrorF("SymInitialize failed, stack trace can not be generated (%lu): %.*s\n", error.code, DN_Str8PrintFmt(error.msg));
|
||||||
DN_TCScratchEnd(&scratch);
|
DN_TCScratchEnd(&scratch);
|
||||||
@@ -1240,7 +1262,9 @@ DN_API DN_StackTraceWalkResult DN_StackTraceWalk(DN_Arena *arena, DN_U16 limit)
|
|||||||
}
|
}
|
||||||
DN_TicketMutex_End(&mutex);
|
DN_TicketMutex_End(&mutex);
|
||||||
|
|
||||||
result.base_addr = DN_ArenaNewArray(arena, DN_U64, raw_frames_count, DN_ZMem_No);
|
result.base_addr = DN_Cast(DN_U64 *)DN_AllocatorAlloc(allocator, raw_frames_count * sizeof(DN_U64), alignof(DN_U64), DN_ZMem_No);
|
||||||
|
DN_Assert(result.base_addr);
|
||||||
|
|
||||||
result.size = DN_Cast(DN_U16) raw_frames_count;
|
result.size = DN_Cast(DN_U16) raw_frames_count;
|
||||||
DN_Memcpy(result.base_addr, raw_frames, raw_frames_count * sizeof(raw_frames[0]));
|
DN_Memcpy(result.base_addr, raw_frames, raw_frames_count * sizeof(raw_frames[0]));
|
||||||
#else
|
#else
|
||||||
@@ -1250,66 +1274,91 @@ DN_API DN_StackTraceWalkResult DN_StackTraceWalk(DN_Arena *arena, DN_U16 limit)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DN_StackTraceAddWalkToStr8Builder(DN_StackTraceWalkResult const *walk, DN_Str8Builder *builder, DN_USize skip)
|
|
||||||
|
DN_API DN_StackTrace DN_StackTraceFromArena(DN_Arena *arena, DN_U16 limit)
|
||||||
|
{
|
||||||
|
DN_Allocator allocator = DN_AllocatorFromArena(arena);
|
||||||
|
DN_StackTrace result = DN_StackTraceFromAllocator(allocator, limit);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DN_StackTraceAddToStr8Builder_(DN_StackTrace const *trace, DN_Str8Builder *builder, DN_USize skip)
|
||||||
{
|
{
|
||||||
DN_StackTraceRawFrame raw_frame = {};
|
DN_StackTraceRawFrame raw_frame = {};
|
||||||
raw_frame.process = walk->process;
|
raw_frame.process = trace->process;
|
||||||
for (DN_USize index = skip; index < walk->size; index++) {
|
for (DN_USize index = skip; index < trace->size; index++) {
|
||||||
raw_frame.base_addr = walk->base_addr[index];
|
raw_frame.base_addr = trace->base_addr[index];
|
||||||
DN_StackTraceFrame frame = DN_StackTraceRawFrameToFrame(builder->arena, raw_frame);
|
DN_StackTraceFrame frame = DN_StackTraceRawFrameToFrame(builder->arena, raw_frame);
|
||||||
DN_Str8BuilderAppendF(builder, "%.*s(%zu): %.*s%s", DN_Str8PrintFmt(frame.file_name), frame.line_number, DN_Str8PrintFmt(frame.function_name), (DN_Cast(int) index == walk->size - 1) ? "" : "\n");
|
DN_Str8BuilderAppendF(builder, "%.*s(%zu): %.*s%s", DN_Str8PrintFmt(frame.file_name), frame.line_number, DN_Str8PrintFmt(frame.function_name), (DN_Cast(int) index == trace->size - 1) ? "" : "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API bool DN_StackTraceWalkResultIterate(DN_StackTraceWalkResultIterator *it, DN_StackTraceWalkResult const *walk)
|
DN_API bool DN_StackTraceIterate(DN_StackTraceIterator *it, DN_StackTrace const *trace)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
if (!it || !walk || !walk->base_addr || !walk->process)
|
if (!it || !trace || !trace->base_addr || !trace->process)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
if (it->index >= walk->size)
|
if (it->index >= trace->size)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
it->raw_frame.process = walk->process;
|
it->raw_frame.process = trace->process;
|
||||||
it->raw_frame.base_addr = walk->base_addr[it->index++];
|
it->raw_frame.base_addr = trace->base_addr[it->index++];
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API DN_Str8 DN_StackTraceWalkResultToStr8(DN_Arena *arena, DN_StackTraceWalkResult const *walk, DN_U16 skip)
|
DN_API DN_Str8 DN_Str8FromStackTraceAllocator(DN_Allocator allocator, DN_StackTrace const *trace, DN_U16 skip)
|
||||||
{
|
{
|
||||||
DN_Str8 result{};
|
DN_Str8 result = {};
|
||||||
if (!walk || !arena)
|
if (!trace)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
|
DN_TCScratch scratch = DN_TCScratchBeginAllocator(&allocator, 1);
|
||||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
|
DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
|
||||||
DN_StackTraceAddWalkToStr8Builder(walk, &builder, skip);
|
DN_StackTraceAddToStr8Builder_(trace, &builder, skip);
|
||||||
result = DN_Str8BuilderBuild(&builder, arena);
|
result = DN_Str8FromStr8BuilderAllocator(&builder, allocator);
|
||||||
DN_TCScratchEnd(&scratch);
|
DN_TCScratchEnd(&scratch);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API DN_Str8 DN_StackTraceWalkStr8(DN_Arena *arena, DN_U16 limit, DN_U16 skip)
|
DN_API DN_Str8 DN_Str8FromStackTraceArena(DN_Arena *arena, DN_StackTrace const *trace, DN_U16 skip)
|
||||||
{
|
{
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
|
DN_Str8 result = {};
|
||||||
DN_StackTraceWalkResult walk = DN_StackTraceWalk(&scratch.arena, limit);
|
if (!trace || !arena)
|
||||||
DN_Str8 result = DN_StackTraceWalkResultToStr8(arena, &walk, skip);
|
return result;
|
||||||
|
|
||||||
|
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||||
|
DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
|
||||||
|
DN_StackTraceAddToStr8Builder_(trace, &builder, skip);
|
||||||
|
result = DN_Str8FromStr8BuilderArena(&builder, arena);
|
||||||
DN_TCScratchEnd(&scratch);
|
DN_TCScratchEnd(&scratch);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_API DN_Str8 DN_StackTraceWalkStr8FromHeap(DN_U16 limit, DN_U16 skip)
|
DN_API DN_Str8 DN_Str8FromStackTraceNowAllocator(DN_Allocator allocator, DN_U16 limit, DN_U16 skip)
|
||||||
{
|
{
|
||||||
// NOTE: We don't use WalkResultToStr8 because that uses the TLS arenas which
|
DN_TCScratch scratch = DN_TCScratchBeginArena(DN_Cast(DN_Arena **) & allocator.context, 1);
|
||||||
// does not use the OS heap.
|
DN_StackTrace walk = DN_StackTraceFromArena(&scratch.arena, limit);
|
||||||
DN_MemList mem = DN_MemListFromHeap(DN_Kilobytes(64), DN_MemFlags_NoAllocTrack);
|
DN_Str8 result = DN_Str8FromStackTraceAllocator(allocator, &walk, skip);
|
||||||
DN_Arena arena = DN_ArenaFromMemList(&mem);
|
DN_TCScratchEnd(&scratch);
|
||||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(&arena);
|
return result;
|
||||||
DN_StackTraceWalkResult walk = DN_StackTraceWalk(&arena, limit);
|
}
|
||||||
DN_StackTraceAddWalkToStr8Builder(&walk, &builder, skip);
|
|
||||||
|
DN_API DN_Str8 DN_Str8FromStackTraceNowArena(DN_Arena *arena, DN_U16 limit, DN_U16 skip)
|
||||||
|
{
|
||||||
|
DN_Str8 result = DN_Str8FromStackTraceNowAllocator(DN_AllocatorFromArena(arena), limit, skip);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DN_API DN_Str8 DN_Str8FromStackTraceNowHeap(DN_U16 limit, DN_U16 skip)
|
||||||
|
{
|
||||||
|
DN_Arena arena = DN_ArenaFromHeap(DN_Kilobytes(64), DN_MemFlags_NoAllocTrack);
|
||||||
|
DN_Str8Builder builder = DN_Str8BuilderFromArena(&arena);
|
||||||
|
DN_StackTrace walk = DN_StackTraceFromArena(&arena, limit);
|
||||||
|
DN_StackTraceAddToStr8Builder_(&walk, &builder, skip);
|
||||||
DN_Str8 result = DN_Str8BuilderBuildFromHeap(&builder);
|
DN_Str8 result = DN_Str8BuilderBuildFromHeap(&builder);
|
||||||
DN_MemListDeinit(&mem);
|
DN_ArenaDeinit(&arena);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1319,12 +1368,12 @@ DN_API DN_StackTraceFrameSlice DN_StackTraceGetFrames(DN_Arena *arena, DN_U16 li
|
|||||||
if (!arena)
|
if (!arena)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||||
DN_StackTraceWalkResult walk = DN_StackTraceWalk(&scratch.arena, limit);
|
DN_StackTrace walk = DN_StackTraceFromArena(&scratch.arena, limit);
|
||||||
if (walk.size) {
|
if (walk.size) {
|
||||||
if (DN_ISliceAllocArena(&result, walk.size, DN_ZMem_No, arena)) {
|
if (DN_ISliceAllocArena(&result, walk.size, DN_ZMem_No, arena)) {
|
||||||
DN_USize slice_index = 0;
|
DN_USize slice_index = 0;
|
||||||
for (DN_StackTraceWalkResultIterator it = {}; DN_StackTraceWalkResultIterate(&it, &walk);)
|
for (DN_StackTraceIterator it = {}; DN_StackTraceIterate(&it, &walk);)
|
||||||
result.data[slice_index++] = DN_StackTraceRawFrameToFrame(arena, it.raw_frame);
|
result.data[slice_index++] = DN_StackTraceRawFrameToFrame(arena, it.raw_frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1381,7 +1430,7 @@ DN_API DN_StackTraceFrame DN_StackTraceRawFrameToFrame(DN_Arena *arena, DN_Stack
|
|||||||
|
|
||||||
DN_API void DN_StackTracePrint(DN_U16 limit)
|
DN_API void DN_StackTracePrint(DN_U16 limit)
|
||||||
{
|
{
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_StackTraceFrameSlice stack_trace = DN_StackTraceGetFrames(&scratch.arena, limit);
|
DN_StackTraceFrameSlice stack_trace = DN_StackTraceGetFrames(&scratch.arena, limit);
|
||||||
for (DN_ForItSize(it, DN_StackTraceFrame, stack_trace.data, stack_trace.count)) {
|
for (DN_ForItSize(it, DN_StackTraceFrame, stack_trace.data, stack_trace.count)) {
|
||||||
DN_StackTraceFrame frame = *it.data;
|
DN_StackTraceFrame frame = *it.data;
|
||||||
|
|||||||
+2
-1
@@ -297,7 +297,8 @@ DN_API DN_MemFuncs DN_MemFuncsFromType (D
|
|||||||
DN_API DN_MemFuncs DN_MemFuncsDefault ();
|
DN_API DN_MemFuncs DN_MemFuncsDefault ();
|
||||||
DN_API DN_MemList DN_MemListFromHeap (DN_U64 size, DN_MemFlags flags);
|
DN_API DN_MemList DN_MemListFromHeap (DN_U64 size, DN_MemFlags flags);
|
||||||
DN_API DN_MemList DN_MemListFromVMem (DN_U64 reserve, DN_U64 commit, DN_MemFlags flags);
|
DN_API DN_MemList DN_MemListFromVMem (DN_U64 reserve, DN_U64 commit, DN_MemFlags flags);
|
||||||
|
DN_API DN_Arena DN_ArenaFromHeap (DN_U64 wize, DN_MemFlags flags);
|
||||||
|
DN_API DN_Arena DN_ArenaFromVMem (DN_U64 reserve, DN_U64 commit, DN_MemFlags flags);
|
||||||
|
|
||||||
DN_API DN_Str8 DN_Str8FromHeapF (DN_FMT_ATTRIB char const *fmt, ...);
|
DN_API DN_Str8 DN_Str8FromHeapF (DN_FMT_ATTRIB char const *fmt, ...);
|
||||||
DN_API DN_Str8 DN_Str8FromHeap (DN_USize size, DN_ZMem z_mem);
|
DN_API DN_Str8 DN_Str8FromHeap (DN_USize size, DN_ZMem z_mem);
|
||||||
|
|||||||
+30
-30
@@ -209,7 +209,7 @@ DN_API void DN_OS_GenBytesSecure(void *buffer, DN_U32 size)
|
|||||||
|
|
||||||
DN_API DN_OSDiskSpace DN_OS_DiskSpace(DN_Str8 path)
|
DN_API DN_OSDiskSpace DN_OS_DiskSpace(DN_Str8 path)
|
||||||
{
|
{
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_OSDiskSpace result = {};
|
DN_OSDiskSpace result = {};
|
||||||
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
|
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
|
||||||
|
|
||||||
@@ -233,7 +233,7 @@ DN_API DN_OSDiskSpace DN_OS_DiskSpace(DN_Str8 path)
|
|||||||
|
|
||||||
DN_API bool DN_OS_SetEnvVar(DN_Str8 name, DN_Str8 value)
|
DN_API bool DN_OS_SetEnvVar(DN_Str8 name, DN_Str8 value)
|
||||||
{
|
{
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str16 name16 = DN_OS_W32Str8ToStr16(&scratch.arena, name);
|
DN_Str16 name16 = DN_OS_W32Str8ToStr16(&scratch.arena, name);
|
||||||
DN_Str16 value16 = DN_OS_W32Str8ToStr16(&scratch.arena, value);
|
DN_Str16 value16 = DN_OS_W32Str8ToStr16(&scratch.arena, value);
|
||||||
bool result = SetEnvironmentVariableW(name16.data, value16.data) != 0;
|
bool result = SetEnvironmentVariableW(name16.data, value16.data) != 0;
|
||||||
@@ -246,7 +246,7 @@ DN_API DN_Str8 DN_OS_EXEPath(DN_Arena *arena)
|
|||||||
DN_Str8 result = {};
|
DN_Str8 result = {};
|
||||||
if (!arena)
|
if (!arena)
|
||||||
return result;
|
return result;
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||||
DN_Str16 exe_dir16 = DN_OS_W32EXEPathW(&scratch.arena);
|
DN_Str16 exe_dir16 = DN_OS_W32EXEPathW(&scratch.arena);
|
||||||
result = DN_OS_W32Str16ToStr8(arena, exe_dir16);
|
result = DN_OS_W32Str16ToStr8(arena, exe_dir16);
|
||||||
DN_TCScratchEnd(&scratch);
|
DN_TCScratchEnd(&scratch);
|
||||||
@@ -286,7 +286,7 @@ static DN_U64 DN_OS_W32FileTimeToSeconds_(FILETIME const *time)
|
|||||||
DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink *err)
|
DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink *err)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str16 src16 = DN_OS_W32Str8ToStr16(&scratch.arena, src);
|
DN_Str16 src16 = DN_OS_W32Str8ToStr16(&scratch.arena, src);
|
||||||
DN_Str16 dest16 = DN_OS_W32Str8ToStr16(&scratch.arena, dest);
|
DN_Str16 dest16 = DN_OS_W32Str8ToStr16(&scratch.arena, dest);
|
||||||
|
|
||||||
@@ -310,7 +310,7 @@ DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink
|
|||||||
DN_API bool DN_OS_FileMove(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink *err)
|
DN_API bool DN_OS_FileMove(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink *err)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str16 src16 = DN_OS_W32Str8ToStr16(&scratch.arena, src);
|
DN_Str16 src16 = DN_OS_W32Str8ToStr16(&scratch.arena, src);
|
||||||
DN_Str16 dest16 = DN_OS_W32Str8ToStr16(&scratch.arena, dest);
|
DN_Str16 dest16 = DN_OS_W32Str8ToStr16(&scratch.arena, dest);
|
||||||
|
|
||||||
@@ -366,7 +366,7 @@ DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path, DN_OSFileOpen open_mode, DN_OSFile
|
|||||||
access_mode |= GENERIC_EXECUTE;
|
access_mode |= GENERIC_EXECUTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
|
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
|
||||||
void *handle = CreateFileW(/*LPCWSTR lpFileName*/ path16.data,
|
void *handle = CreateFileW(/*LPCWSTR lpFileName*/ path16.data,
|
||||||
/*DWORD dwDesiredAccess*/ access_mode,
|
/*DWORD dwDesiredAccess*/ access_mode,
|
||||||
@@ -395,9 +395,9 @@ DN_API DN_OSFileRead DN_OS_FileRead(DN_OSFile *file, void *buffer, DN_USize size
|
|||||||
if (!file || !file->handle || file->error || !buffer || size <= 0)
|
if (!file || !file->handle || file->error || !buffer || size <= 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
if (!DN_Check(size <= (unsigned long)-1)) {
|
if (!DN_Check(size <= (unsigned long)-1)) {
|
||||||
DN_Str8x32 buffer_size_str8 = DN_ByteCountStr8x32(size);
|
DN_Str8x32 buffer_size_str8 = DN_Str8x32FromByteCountU64Auto(size);
|
||||||
DN_ErrSinkAppendF(
|
DN_ErrSinkAppendF(
|
||||||
err,
|
err,
|
||||||
1 /*error_code*/,
|
1 /*error_code*/,
|
||||||
@@ -455,9 +455,9 @@ DN_API bool DN_OS_FileWritePtr(DN_OSFile *file, void const *buffer, DN_USize siz
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_OSW32Error win_error = DN_OS_W32LastError(&scratch.arena);
|
DN_OSW32Error win_error = DN_OS_W32LastError(&scratch.arena);
|
||||||
DN_Str8x32 buffer_size_str8 = DN_ByteCountStr8x32(size);
|
DN_Str8x32 buffer_size_str8 = DN_Str8x32FromByteCountU64Auto(size);
|
||||||
DN_ErrSinkAppendF(err, win_error.code, "Failed to write buffer (%.*s) to file handle: %.*s", DN_Str8PrintFmt(buffer_size_str8), DN_Str8PrintFmt(win_error.msg));
|
DN_ErrSinkAppendF(err, win_error.code, "Failed to write buffer (%.*s) to file handle: %.*s", DN_Str8PrintFmt(buffer_size_str8), DN_Str8PrintFmt(win_error.msg));
|
||||||
DN_TCScratchEnd(&scratch);
|
DN_TCScratchEnd(&scratch);
|
||||||
}
|
}
|
||||||
@@ -471,7 +471,7 @@ DN_API bool DN_OS_FileFlush(DN_OSFile *file, DN_ErrSink *err)
|
|||||||
|
|
||||||
BOOL result = FlushFileBuffers(DN_Cast(HANDLE) file->handle);
|
BOOL result = FlushFileBuffers(DN_Cast(HANDLE) file->handle);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_OSW32Error win_error = DN_OS_W32LastError(&scratch.arena);
|
DN_OSW32Error win_error = DN_OS_W32LastError(&scratch.arena);
|
||||||
DN_ErrSinkAppendF(err, win_error.code, "Failed to flush file buffer to disk: %.*s", DN_Str8PrintFmt(win_error.msg));
|
DN_ErrSinkAppendF(err, win_error.code, "Failed to flush file buffer to disk: %.*s", DN_Str8PrintFmt(win_error.msg));
|
||||||
DN_TCScratchEnd(&scratch);
|
DN_TCScratchEnd(&scratch);
|
||||||
@@ -494,7 +494,7 @@ DN_API DN_OSPathInfo DN_OS_PathInfo(DN_Str8 path)
|
|||||||
if (path.size == 0)
|
if (path.size == 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
|
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
|
||||||
|
|
||||||
WIN32_FILE_ATTRIBUTE_DATA attrib_data = {};
|
WIN32_FILE_ATTRIBUTE_DATA attrib_data = {};
|
||||||
@@ -530,7 +530,7 @@ DN_API bool DN_OS_PathDelete(DN_Str8 path)
|
|||||||
if (path.size == 0)
|
if (path.size == 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
|
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
|
||||||
if (path16.size) {
|
if (path16.size) {
|
||||||
result = DeleteFileW(path16.data);
|
result = DeleteFileW(path16.data);
|
||||||
@@ -547,7 +547,7 @@ DN_API bool DN_OS_PathIsFile(DN_Str8 path)
|
|||||||
if (path.size == 0)
|
if (path.size == 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
|
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
|
||||||
if (path16.size) {
|
if (path16.size) {
|
||||||
WIN32_FILE_ATTRIBUTE_DATA attrib_data = {};
|
WIN32_FILE_ATTRIBUTE_DATA attrib_data = {};
|
||||||
@@ -565,7 +565,7 @@ DN_API bool DN_OS_PathIsDir(DN_Str8 path)
|
|||||||
if (path.size == 0)
|
if (path.size == 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
|
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
|
||||||
if (path16.size) {
|
if (path16.size) {
|
||||||
WIN32_FILE_ATTRIBUTE_DATA attrib_data = {};
|
WIN32_FILE_ATTRIBUTE_DATA attrib_data = {};
|
||||||
@@ -581,7 +581,7 @@ DN_API bool DN_OS_PathIsDir(DN_Str8 path)
|
|||||||
DN_API bool DN_OS_PathMakeDir(DN_Str8 path)
|
DN_API bool DN_OS_PathMakeDir(DN_Str8 path)
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
|
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
|
||||||
|
|
||||||
// NOTE: Go back from the end of the string to all the directories in the
|
// NOTE: Go back from the end of the string to all the directories in the
|
||||||
@@ -636,7 +636,7 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it)
|
|||||||
if (path.size == 0 || !it || path.size <= 0)
|
if (path.size == 0 || !it || path.size <= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_OSW32FolderIteratorW wide_it = {};
|
DN_OSW32FolderIteratorW wide_it = {};
|
||||||
DN_Str16 path16 = {};
|
DN_Str16 path16 = {};
|
||||||
if (it->handle) {
|
if (it->handle) {
|
||||||
@@ -716,7 +716,7 @@ DN_API DN_OSExecResult DN_OS_ExecPump(DN_OSExecAsyncHandle handle,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DWORD stdout_bytes_available = 0;
|
DWORD stdout_bytes_available = 0;
|
||||||
DWORD stderr_bytes_available = 0;
|
DWORD stderr_bytes_available = 0;
|
||||||
PeekNamedPipe(handle.stdout_read, nullptr, 0, nullptr, &stdout_bytes_available, nullptr);
|
PeekNamedPipe(handle.stdout_read, nullptr, 0, nullptr, &stdout_bytes_available, nullptr);
|
||||||
@@ -822,7 +822,7 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle, DN_Arena *are
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||||
DN_Str8Builder stdout_builder = {};
|
DN_Str8Builder stdout_builder = {};
|
||||||
DN_Str8Builder stderr_builder = {};
|
DN_Str8Builder stderr_builder = {};
|
||||||
if (arena) {
|
if (arena) {
|
||||||
@@ -845,8 +845,8 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle, DN_Arena *are
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Get stdout/stderr. If no arena is passed this is a no-op
|
// NOTE: Get stdout/stderr. If no arena is passed this is a no-op
|
||||||
result.stdout_text = DN_Str8BuilderBuild(&stdout_builder, arena);
|
result.stdout_text = DN_Str8FromStr8BuilderArena(&stdout_builder, arena);
|
||||||
result.stderr_text = DN_Str8BuilderBuild(&stderr_builder, arena);
|
result.stderr_text = DN_Str8FromStr8BuilderArena(&stderr_builder, arena);
|
||||||
DN_TCScratchEnd(&scratch);
|
DN_TCScratchEnd(&scratch);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -858,7 +858,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line, DN_OSExecArgs
|
|||||||
if (cmd_line.count == 0)
|
if (cmd_line.count == 0)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str8 cmd_rendered = DN_Str8SliceRender(cmd_line, DN_Str8Lit(" "), &scratch.arena);
|
DN_Str8 cmd_rendered = DN_Str8SliceRender(cmd_line, DN_Str8Lit(" "), &scratch.arena);
|
||||||
DN_Str16 cmd16 = DN_OS_W32Str8ToStr16(&scratch.arena, cmd_rendered);
|
DN_Str16 cmd16 = DN_OS_W32Str8ToStr16(&scratch.arena, cmd_rendered);
|
||||||
DN_Str16 working_dir16 = DN_OS_W32Str8ToStr16(&scratch.arena, args->working_dir);
|
DN_Str16 working_dir16 = DN_OS_W32Str8ToStr16(&scratch.arena, args->working_dir);
|
||||||
@@ -868,7 +868,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line, DN_OSExecArgs
|
|||||||
if (env_builder.string_size)
|
if (env_builder.string_size)
|
||||||
DN_Str8BuilderAppendRef(&env_builder, DN_Str8Lit("\0"));
|
DN_Str8BuilderAppendRef(&env_builder, DN_Str8Lit("\0"));
|
||||||
|
|
||||||
DN_Str8 env_block8 = DN_Str8BuilderBuildDelimited(&env_builder, DN_Str8Lit("\0"), &scratch.arena);
|
DN_Str8 env_block8 = DN_Str8FromStr8BuilderDelimitArena(&env_builder, DN_Str8Lit("\0"), &scratch.arena);
|
||||||
DN_Str16 env_block16 = {};
|
DN_Str16 env_block16 = {};
|
||||||
if (env_block8.size)
|
if (env_block8.size)
|
||||||
env_block16 = DN_OS_W32Str8ToStr16(&scratch.arena, env_block8);
|
env_block16 = DN_OS_W32Str8ToStr16(&scratch.arena, env_block8);
|
||||||
@@ -1305,7 +1305,7 @@ DN_API void DN_OS_W32ThreadSetName(DN_Str8 name)
|
|||||||
//
|
//
|
||||||
// See: https://learn.microsoft.com/en-us/windows/w32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription
|
// See: https://learn.microsoft.com/en-us/windows/w32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription
|
||||||
DN_OSW32Core *w32 = DN_OS_W32GetCore();
|
DN_OSW32Core *w32 = DN_OS_W32GetCore();
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
if (w32->set_thread_description) {
|
if (w32->set_thread_description) {
|
||||||
DN_Str16 name16 = DN_OS_W32Str8ToStr16(&scratch.arena, name);
|
DN_Str16 name16 = DN_OS_W32Str8ToStr16(&scratch.arena, name);
|
||||||
w32->set_thread_description(GetCurrentThread(), (WCHAR *)name16.data);
|
w32->set_thread_description(GetCurrentThread(), (WCHAR *)name16.data);
|
||||||
@@ -1420,7 +1420,7 @@ void DN_OS_HttpRequestWin32Callback(HINTERNET session, DWORD *dwContext, DWORD d
|
|||||||
if (request) {
|
if (request) {
|
||||||
bool read_complete = dwInternetStatus == WINHTTP_CALLBACK_STATUS_READ_COMPLETE && dwStatusInformationLength == 0;
|
bool read_complete = dwInternetStatus == WINHTTP_CALLBACK_STATUS_READ_COMPLETE && dwStatusInformationLength == 0;
|
||||||
if (read_complete)
|
if (read_complete)
|
||||||
response->body = DN_Str8BuilderBuild(&response->builder, response->arena);
|
response->body = DN_Str8FromStr8BuilderArena(&response->builder, response->arena);
|
||||||
|
|
||||||
if (read_complete || dwInternetStatus == WINHTTP_CALLBACK_STATUS_REQUEST_ERROR || error.code) {
|
if (read_complete || dwInternetStatus == WINHTTP_CALLBACK_STATUS_REQUEST_ERROR || error.code) {
|
||||||
DN_OS_SemaphoreIncrement(&response->on_complete_semaphore, 1);
|
DN_OS_SemaphoreIncrement(&response->on_complete_semaphore, 1);
|
||||||
@@ -1449,7 +1449,7 @@ DN_API void DN_OS_HttpRequestAsync(DN_OSHttpResponse *response,
|
|||||||
response->arena = arena;
|
response->arena = arena;
|
||||||
response->builder = DN_Str8BuilderFromArena(response->scratch_arena.mem ? &response->scratch_arena : &response->tmp_arena);
|
response->builder = DN_Str8BuilderFromArena(response->scratch_arena.mem ? &response->scratch_arena : &response->tmp_arena);
|
||||||
|
|
||||||
DN_TCScratch scratch_ = DN_TCScratchBegin(&arena, 1);
|
DN_TCScratch scratch_ = DN_TCScratchBeginArena(&arena, 1);
|
||||||
if (!response->scratch_arena.mem)
|
if (!response->scratch_arena.mem)
|
||||||
response->scratch_arena = scratch_.arena;
|
response->scratch_arena = scratch_.arena;
|
||||||
|
|
||||||
@@ -1743,7 +1743,7 @@ DN_API DN_Str8 DN_OS_W32Str16ToStr8FromHeap(DN_Str16 src)
|
|||||||
// NOTE: Windows Executable Directory //////////////////////////////////////////
|
// NOTE: Windows Executable Directory //////////////////////////////////////////
|
||||||
DN_API DN_Str16 DN_OS_W32EXEPathW(DN_Arena *arena)
|
DN_API DN_Str16 DN_OS_W32EXEPathW(DN_Arena *arena)
|
||||||
{
|
{
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||||
DN_Str16 result = {};
|
DN_Str16 result = {};
|
||||||
DN_USize module_size = 0;
|
DN_USize module_size = 0;
|
||||||
wchar_t *module_path = nullptr;
|
wchar_t *module_path = nullptr;
|
||||||
@@ -1772,7 +1772,7 @@ DN_API DN_Str16 DN_OS_W32EXEPathW(DN_Arena *arena)
|
|||||||
DN_API DN_Str16 DN_OS_W32EXEDirW(DN_Arena *arena)
|
DN_API DN_Str16 DN_OS_W32EXEDirW(DN_Arena *arena)
|
||||||
{
|
{
|
||||||
// TODO(doyle): Implement a DN_Str16_BinarySearchReverse
|
// TODO(doyle): Implement a DN_Str16_BinarySearchReverse
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||||
DN_Str16 result = {};
|
DN_Str16 result = {};
|
||||||
DN_USize module_size = 0;
|
DN_USize module_size = 0;
|
||||||
wchar_t *module_path = nullptr;
|
wchar_t *module_path = nullptr;
|
||||||
@@ -1800,7 +1800,7 @@ DN_API DN_Str16 DN_OS_W32EXEDirW(DN_Arena *arena)
|
|||||||
|
|
||||||
DN_API DN_Str8 DN_OS_W32WorkingDir(DN_Arena *arena, DN_Str8 suffix)
|
DN_API DN_Str8 DN_OS_W32WorkingDir(DN_Arena *arena, DN_Str8 suffix)
|
||||||
{
|
{
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||||
DN_Str16 suffix16 = DN_OS_W32Str8ToStr16(&scratch.arena, suffix);
|
DN_Str16 suffix16 = DN_OS_W32Str8ToStr16(&scratch.arena, suffix);
|
||||||
DN_Str16 dir16 = DN_OS_W32WorkingDirW(&scratch.arena, suffix16);
|
DN_Str16 dir16 = DN_OS_W32WorkingDirW(&scratch.arena, suffix16);
|
||||||
DN_Str8 result = DN_OS_W32Str16ToStr8(arena, dir16);
|
DN_Str8 result = DN_OS_W32Str16ToStr8(arena, dir16);
|
||||||
@@ -1814,7 +1814,7 @@ DN_API DN_Str16 DN_OS_W32WorkingDirW(DN_Arena *arena, DN_Str16 suffix)
|
|||||||
DN_Str16 result = {};
|
DN_Str16 result = {};
|
||||||
|
|
||||||
// NOTE: required_size is the size required *including* the null-terminator
|
// NOTE: required_size is the size required *including* the null-terminator
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||||
unsigned long required_size = GetCurrentDirectoryW(0, nullptr);
|
unsigned long required_size = GetCurrentDirectoryW(0, nullptr);
|
||||||
unsigned long desired_size = required_size + DN_Cast(unsigned long) suffix.size;
|
unsigned long desired_size = required_size + DN_Cast(unsigned long) suffix.size;
|
||||||
|
|
||||||
|
|||||||
+14
-21
@@ -20,7 +20,7 @@ DN_Core *g_dn_;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DN_API void DN_Init(DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args)
|
DN_API void DN_Init(DN_Core *dn, DN_InitFlags flags, DN_TCInitArgs args)
|
||||||
{
|
{
|
||||||
DN_Set(dn);
|
DN_Set(dn);
|
||||||
dn->init_flags = flags;
|
dn->init_flags = flags;
|
||||||
@@ -106,8 +106,7 @@ DN_API void DN_Init(DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args)
|
|||||||
if (DN_BitIsSet(flags, DN_InitFlags_ThreadContext)) {
|
if (DN_BitIsSet(flags, DN_InitFlags_ThreadContext)) {
|
||||||
DN_Assert(dn->os_init);
|
DN_Assert(dn->os_init);
|
||||||
#if DN_H_WITH_OS
|
#if DN_H_WITH_OS
|
||||||
DN_TCInitArgs *tc_init_args = args ? &args->thread_context_init_args : nullptr;
|
DN_TCInitFromMemFuncs(&dn->main_tc, DN_OS_ThreadID(), args, DN_MemFuncsDefault());
|
||||||
DN_TCInitFromMemFuncs(&dn->main_tc, DN_OS_ThreadID(), tc_init_args, DN_MemFuncsDefault());
|
|
||||||
DN_TCEquip(&dn->main_tc);
|
DN_TCEquip(&dn->main_tc);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -139,24 +138,18 @@ DN_API void DN_Init(DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args)
|
|||||||
case DN_MemFuncsType_Heap: mem_funcs = DN_Str8Lit("Heap"); break;
|
case DN_MemFuncsType_Heap: mem_funcs = DN_Str8Lit("Heap"); break;
|
||||||
case DN_MemFuncsType_Virtual: mem_funcs = DN_Str8Lit("Virtual"); break;
|
case DN_MemFuncsType_Virtual: mem_funcs = DN_Str8Lit("Virtual"); break;
|
||||||
}
|
}
|
||||||
DN_Str8x32 main_commit = DN_ByteCountStr8x32(dn->main_tc.main_arena->mem->curr->commit);
|
DN_Str8x32 main_commit = DN_Str8x32FromByteCountU64Auto(dn->main_tc.main_arena->mem->curr->commit);
|
||||||
DN_Str8x32 main_reserve = DN_ByteCountStr8x32(dn->main_tc.main_arena->mem->curr->reserve);
|
DN_Str8x32 main_reserve = DN_Str8x32FromByteCountU64Auto(dn->main_tc.main_arena->mem->curr->reserve);
|
||||||
DN_Str8x32 temp_commit = DN_ByteCountStr8x32(dn->main_tc.temp_a_arena->mem->curr->commit);
|
DN_Str8x32 err_commit = DN_Str8x32FromByteCountU64Auto(dn->main_tc.err_sink.arena->mem->curr->commit);
|
||||||
DN_Str8x32 temp_reserve = DN_ByteCountStr8x32(dn->main_tc.temp_a_arena->mem->curr->reserve);
|
DN_Str8x32 err_reserve = DN_Str8x32FromByteCountU64Auto(dn->main_tc.err_sink.arena->mem->curr->reserve);
|
||||||
DN_Str8x32 err_commit = DN_ByteCountStr8x32(dn->main_tc.err_sink.arena->mem->curr->commit);
|
DN_FmtAppendTruncate(buf, &buf_size, sizeof(buf), DN_Str8Lit("..."), "M %.*s/%.*s", DN_Str8PrintFmt(main_commit), DN_Str8PrintFmt(main_reserve));
|
||||||
DN_Str8x32 err_reserve = DN_ByteCountStr8x32(dn->main_tc.err_sink.arena->mem->curr->reserve);
|
if (dn->main_tc.temp_arenas_count) {
|
||||||
DN_FmtAppendTruncate(buf,
|
DN_Arena *temp = dn->main_tc.temp_arenas[0];
|
||||||
&buf_size,
|
DN_Str8x32 temp_commit = DN_Str8x32FromByteCountU64Auto(temp->mem->curr->commit);
|
||||||
sizeof(buf),
|
DN_Str8x32 temp_reserve = DN_Str8x32FromByteCountU64Auto(temp->mem->curr->reserve);
|
||||||
DN_Str8Lit("..."),
|
DN_FmtAppendTruncate(buf, &buf_size, sizeof(buf), DN_Str8Lit("..."), " T(x%zu) %.*s/%.*s", dn->main_tc.temp_arenas_count, DN_Str8PrintFmt(temp_commit), DN_Str8PrintFmt(temp_reserve));
|
||||||
"M %.*s/%.*s S(x2) %.*s/%.*s E %.*s/%.*s (%.*s)\n",
|
}
|
||||||
DN_Str8PrintFmt(main_commit),
|
DN_FmtAppendTruncate(buf, &buf_size, sizeof(buf), DN_Str8Lit("..."), " E %.*s/%.*s (%.*s)\n", DN_Str8PrintFmt(err_commit), DN_Str8PrintFmt(err_reserve), DN_Str8PrintFmt(mem_funcs));
|
||||||
DN_Str8PrintFmt(main_reserve),
|
|
||||||
DN_Str8PrintFmt(temp_commit),
|
|
||||||
DN_Str8PrintFmt(temp_reserve),
|
|
||||||
DN_Str8PrintFmt(err_commit),
|
|
||||||
DN_Str8PrintFmt(err_reserve),
|
|
||||||
DN_Str8PrintFmt(mem_funcs));
|
|
||||||
} else {
|
} else {
|
||||||
DN_FmtAppendTruncate(buf, &buf_size, sizeof(buf), DN_Str8Lit("..."), "N/A\n");
|
DN_FmtAppendTruncate(buf, &buf_size, sizeof(buf), DN_Str8Lit("..."), "N/A\n");
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-8
@@ -143,8 +143,6 @@
|
|||||||
// occurs.
|
// occurs.
|
||||||
|
|
||||||
#include "Base/dn_base.h"
|
#include "Base/dn_base.h"
|
||||||
#include "Base/dn_base_assert.h"
|
|
||||||
#include "Base/dn_base_containers.h"
|
|
||||||
#include "Base/dn_base_leak.h"
|
#include "Base/dn_base_leak.h"
|
||||||
|
|
||||||
#if DN_H_WITH_OS
|
#if DN_H_WITH_OS
|
||||||
@@ -159,11 +157,6 @@
|
|||||||
#include "OS/dn_os.h"
|
#include "OS/dn_os.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct DN_InitArgs
|
|
||||||
{
|
|
||||||
DN_TCInitArgs thread_context_init_args;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef DN_USize DN_InitFlags;
|
typedef DN_USize DN_InitFlags;
|
||||||
enum DN_InitFlags_
|
enum DN_InitFlags_
|
||||||
{
|
{
|
||||||
@@ -193,7 +186,7 @@ struct DN_Core
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
DN_API void DN_Init (DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args);
|
DN_API void DN_Init (DN_Core *dn, DN_InitFlags flags, DN_TCInitArgs args);
|
||||||
DN_API void DN_Set (DN_Core *dn);
|
DN_API void DN_Set (DN_Core *dn);
|
||||||
DN_API DN_Core *DN_Get ();
|
DN_API DN_Core *DN_Get ();
|
||||||
DN_API void DN_BeginFrame();
|
DN_API void DN_BeginFrame();
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ struct File
|
|||||||
|
|
||||||
static void AppendCppFileLineByLine(DN_Str8Builder *dest, DN_Str8 cpp_path)
|
static void AppendCppFileLineByLine(DN_Str8Builder *dest, DN_Str8 cpp_path)
|
||||||
{
|
{
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(&dest->arena, 1);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(&dest->arena, 1);
|
||||||
DN_ErrSink *err = DN_TCErrSinkBeginDefault();
|
DN_ErrSink *err = DN_TCErrSinkBeginDefault();
|
||||||
DN_Str8 buffer = DN_OS_FileReadAllArena(&scratch.arena, cpp_path, err);
|
DN_Str8 buffer = DN_OS_FileReadAllArena(&scratch.arena, cpp_path, err);
|
||||||
DN_ErrSinkEndExitIfErrorF(err, -1, "Failed to load file from '%S' for appending", cpp_path);
|
DN_ErrSinkEndExitIfErrorF(err, -1, "Failed to load file from '%S' for appending", cpp_path);
|
||||||
@@ -93,7 +93,7 @@ static void AppendCppFileLineByLine(DN_Str8Builder *dest, DN_Str8 cpp_path)
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
DN_Core dn = {};
|
DN_Core dn = {};
|
||||||
DN_Init(&dn, DN_InitFlags_OS | DN_InitFlags_ThreadContext, nullptr);
|
DN_Init(&dn, DN_InitFlags_OS | DN_InitFlags_ThreadContext, DN_TCInitArgsDefault());
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc != 3) {
|
||||||
DN_OS_PrintErrF("USAGE: %s <path/to/dn/Source> <output_dir>", argv[0]);
|
DN_OS_PrintErrF("USAGE: %s <path/to/dn/Source> <output_dir>", argv[0]);
|
||||||
@@ -114,7 +114,7 @@ int main(int argc, char **argv)
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (DN_ForIndexU(type, FileType_Count)) {
|
for (DN_ForIndexU(type, FileType_Count)) {
|
||||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
|
DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
|
||||||
DN_Str8 suffix = type == FileType_Header ? DN_Str8Lit("h") : DN_Str8Lit("cpp");
|
DN_Str8 suffix = type == FileType_Header ? DN_Str8Lit("h") : DN_Str8Lit("cpp");
|
||||||
for (DN_ForItCArray(it, DN_Str8 const, REL_FILE_PATHS)) {
|
for (DN_ForItCArray(it, DN_Str8 const, REL_FILE_PATHS)) {
|
||||||
@@ -125,7 +125,7 @@ int main(int argc, char **argv)
|
|||||||
DN_Date date = DN_OS_DateLocalTimeNow();
|
DN_Date date = DN_OS_DateLocalTimeNow();
|
||||||
DN_Str8BuilderPrependF(&builder, "// Generated by the DN single header generator %04u-%02u-%02u %02u:%02u:%02u\n\n", date.year, date.month, date.day, date.hour, date.minutes, date.seconds);
|
DN_Str8BuilderPrependF(&builder, "// Generated by the DN single header generator %04u-%02u-%02u %02u:%02u:%02u\n\n", date.year, date.month, date.day, date.hour, date.minutes, date.seconds);
|
||||||
|
|
||||||
DN_Str8 buffer = DN_Str8TrimWhitespaceAround(DN_Str8BuilderBuild(&builder, &scratch.arena));
|
DN_Str8 buffer = DN_Str8TrimWhitespaceAround(DN_Str8FromStr8BuilderArena(&builder, &scratch.arena));
|
||||||
DN_Str8 single_header_path = DN_OS_PathF(&scratch.arena, "%S/dn_single_header.%S", output_dir, suffix);
|
DN_Str8 single_header_path = DN_OS_PathF(&scratch.arena, "%S/dn_single_header.%S", output_dir, suffix);
|
||||||
DN_ErrSink *err = DN_TCErrSinkBeginDefault();
|
DN_ErrSink *err = DN_TCErrSinkBeginDefault();
|
||||||
DN_OS_FileWriteAllSafe(single_header_path, buffer, err);
|
DN_OS_FileWriteAllSafe(single_header_path, buffer, err);
|
||||||
|
|||||||
Reference in New Issue
Block a user