Fix emcc, msvc and clang builds
This commit is contained in:
+17484
-5
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
// Generated by the DN single header generator 2026-05-18 11:16:15
|
||||
// Generated by the DN single header generator 2026-05-18 12:42:12
|
||||
|
||||
#if !defined(DN_H)
|
||||
#define DN_H
|
||||
@@ -7529,62 +7529,6 @@ void DN_NET_EndFinishedRequest_ (DN_NETRequest *request);
|
||||
#endif // DN_NET_H
|
||||
#endif
|
||||
#endif // !defined(DN_H)
|
||||
#if !defined(DN_ASYNC_H)
|
||||
#define DN_ASYNC_H
|
||||
|
||||
// DN: Single header generator commented out => #if defined(_CLANGD)
|
||||
// #define DN_H_WITH_OS 1
|
||||
// #include "../dn.h"
|
||||
// #endif
|
||||
|
||||
enum DN_ASYNCPriority
|
||||
{
|
||||
DN_ASYNCPriority_Low,
|
||||
DN_ASYNCPriority_High,
|
||||
DN_ASYNCPriority_Count,
|
||||
};
|
||||
|
||||
struct DN_ASYNCCore
|
||||
{
|
||||
DN_OSMutex ring_mutex;
|
||||
DN_OSConditionVariable ring_write_cv;
|
||||
DN_OSSemaphore worker_sem;
|
||||
DN_Ring ring;
|
||||
DN_OSThread *threads;
|
||||
DN_U32 thread_count;
|
||||
DN_U32 busy_threads;
|
||||
DN_U32 join_threads;
|
||||
};
|
||||
|
||||
struct DN_ASYNCWorkArgs
|
||||
{
|
||||
DN_OSThread *thread;
|
||||
void *input;
|
||||
};
|
||||
|
||||
typedef void(DN_ASYNCWorkFunc)(DN_ASYNCWorkArgs work_args);
|
||||
|
||||
struct DN_ASYNCWork
|
||||
{
|
||||
DN_ASYNCWorkFunc *func;
|
||||
void *input;
|
||||
void *output;
|
||||
};
|
||||
|
||||
struct DN_ASYNCTask
|
||||
{
|
||||
bool queued;
|
||||
DN_ASYNCWork work;
|
||||
DN_OSSemaphore completion_sem;
|
||||
};
|
||||
|
||||
DN_API void DN_ASYNC_Init (DN_ASYNCCore *async, char *base, DN_USize base_size, DN_OSThread *threads, DN_U32 threads_size);
|
||||
DN_API void DN_ASYNC_Deinit (DN_ASYNCCore *async);
|
||||
DN_API bool DN_ASYNC_QueueWork(DN_ASYNCCore *async, DN_ASYNCWorkFunc *func, void *input, DN_U64 wait_time_ms);
|
||||
DN_API DN_ASYNCTask DN_ASYNC_QueueTask(DN_ASYNCCore *async, DN_ASYNCWorkFunc *func, void *input, DN_U64 wait_time_ms);
|
||||
DN_API void DN_ASYNC_WaitTask (DN_OSSemaphore *sem, DN_U32 timeout_ms);
|
||||
|
||||
#endif // DN_ASYNC_H
|
||||
#if !defined(DN_BIN_PACK_H)
|
||||
#define DN_BIN_PACK_H
|
||||
|
||||
@@ -7694,267 +7638,3 @@ void DN_CSV_PackBufferWithMax (DN_CSVPack *pack, DN_CSVSerialise se
|
||||
bool DN_CSV_PackNewLine (DN_CSVPack *pack, DN_CSVSerialise serialise);
|
||||
|
||||
#endif // !defined(DN_CSV_H)
|
||||
#if !defined(DN_HELPERS_H)
|
||||
#define DN_HELPERS_H
|
||||
|
||||
// DN: Single header generator commented out => #if defined(_CLANGD)
|
||||
// #include "../dn.h"
|
||||
// #endif
|
||||
|
||||
/*
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// $$\ $$\ $$$$$$$$\ $$\ $$$$$$$\ $$$$$$$$\ $$$$$$$\ $$$$$$\
|
||||
// $$ | $$ |$$ _____|$$ | $$ __$$\ $$ _____|$$ __$$\ $$ __$$\
|
||||
// $$ | $$ |$$ | $$ | $$ | $$ |$$ | $$ | $$ |$$ / \__|
|
||||
// $$$$$$$$ |$$$$$\ $$ | $$$$$$$ |$$$$$\ $$$$$$$ |\$$$$$$\
|
||||
// $$ __$$ |$$ __| $$ | $$ ____/ $$ __| $$ __$$< \____$$\
|
||||
// $$ | $$ |$$ | $$ | $$ | $$ | $$ | $$ |$$\ $$ |
|
||||
// $$ | $$ |$$$$$$$$\ $$$$$$$$\ $$ | $$$$$$$$\ $$ | $$ |\$$$$$$ |
|
||||
// \__| \__|\________|\________|\__| \________|\__| \__| \______/
|
||||
//
|
||||
// dn_helpers.h -- Helper functions/data structures
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
|
||||
#if !defined(DN_NO_JSON_BUILDER)
|
||||
enum DN_JSONBuilderItem
|
||||
{
|
||||
DN_JSONBuilderItem_Empty,
|
||||
DN_JSONBuilderItem_OpenContainer,
|
||||
DN_JSONBuilderItem_CloseContainer,
|
||||
DN_JSONBuilderItem_KeyValue,
|
||||
};
|
||||
|
||||
struct DN_JSONBuilder
|
||||
{
|
||||
bool use_stdout; // When set, ignore the string builder and dump immediately to stdout
|
||||
DN_Str8Builder string_builder; // (Internal)
|
||||
int indent_level; // (Internal)
|
||||
int spaces_per_indent; // The number of spaces per indent level
|
||||
DN_JSONBuilderItem last_item;
|
||||
};
|
||||
#endif // !defined(DN_NO_JSON_BUIDLER)
|
||||
|
||||
template <typename T>
|
||||
using DN_BinarySearchLessThanProc = bool(T const &lhs, T const &rhs);
|
||||
|
||||
template <typename T>
|
||||
bool DN_BinarySearch_DefaultLessThan(T const &lhs, T const &rhs);
|
||||
|
||||
enum DN_BinarySearchType
|
||||
{
|
||||
// Index of the match. If no match is found, found is set to false and the
|
||||
// index is set to the index where the match should be inserted/exist, if
|
||||
// it were in the array
|
||||
DN_BinarySearchType_Match,
|
||||
|
||||
// Index of the first element in the array that is `element >= find`. If no such
|
||||
// item is found or the array is empty, then, the index is set to the array
|
||||
// size and found is set to `false`.
|
||||
//
|
||||
// For example:
|
||||
// int array[] = {0, 1, 2, 3, 4, 5};
|
||||
// DN_BinarySearchResult result = DN_BinarySearch(array, DN_ArrayCountU(array), 4, DN_BinarySearchType_LowerBound);
|
||||
// printf("%zu\n", result.index); // Prints index '4'
|
||||
|
||||
DN_BinarySearchType_LowerBound,
|
||||
|
||||
// Index of the first element in the array that is `element > find`. If no such
|
||||
// item is found or the array is empty, then, the index is set to the array
|
||||
// size and found is set to `false`.
|
||||
//
|
||||
// For example:
|
||||
// int array[] = {0, 1, 2, 3, 4, 5};
|
||||
// DN_BinarySearchResult result = DN_BinarySearch(array, DN_ArrayCountU(array), 4, DN_BinarySearchType_UpperBound);
|
||||
// printf("%zu\n", result.index); // Prints index '5'
|
||||
|
||||
DN_BinarySearchType_UpperBound,
|
||||
};
|
||||
|
||||
struct DN_BinarySearchResult
|
||||
{
|
||||
bool found;
|
||||
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)
|
||||
// NOTE: DN_JSONBuilder ////////////////////////////////////////////////////////////////////////////
|
||||
#define DN_JSONBuilder_Object(builder) \
|
||||
DN_DeferLoop(DN_JSONBuilder_ObjectBegin(builder), \
|
||||
DN_JSONBuilder_ObjectEnd(builder))
|
||||
|
||||
#define DN_JSONBuilder_ObjectNamed(builder, name) \
|
||||
DN_DeferLoop(DN_JSONBuilder_ObjectBeginNamed(builder, name), \
|
||||
DN_JSONBuilder_ObjectEnd(builder))
|
||||
|
||||
#define DN_JSONBuilder_Array(builder) \
|
||||
DN_DeferLoop(DN_JSONBuilder_ArrayBegin(builder), \
|
||||
DN_JSONBuilder_ArrayEnd(builder))
|
||||
|
||||
#define DN_JSONBuilder_ArrayNamed(builder, name) \
|
||||
DN_DeferLoop(DN_JSONBuilder_ArrayBeginNamed(builder, name), \
|
||||
DN_JSONBuilder_ArrayEnd(builder))
|
||||
|
||||
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 void DN_JSONBuilder_KeyValue (DN_JSONBuilder *builder, DN_Str8 key, DN_Str8 value);
|
||||
DN_API void DN_JSONBuilder_KeyValueF (DN_JSONBuilder *builder, DN_Str8 key, char const *value_fmt, ...);
|
||||
DN_API void DN_JSONBuilder_ObjectBeginNamed (DN_JSONBuilder *builder, DN_Str8 name);
|
||||
DN_API void DN_JSONBuilder_ObjectEnd (DN_JSONBuilder *builder);
|
||||
DN_API void DN_JSONBuilder_ArrayBeginNamed (DN_JSONBuilder *builder, DN_Str8 name);
|
||||
DN_API void DN_JSONBuilder_ArrayEnd (DN_JSONBuilder *builder);
|
||||
DN_API void DN_JSONBuilder_Str8Named (DN_JSONBuilder *builder, DN_Str8 key, DN_Str8 value);
|
||||
DN_API void DN_JSONBuilder_LiteralNamed (DN_JSONBuilder *builder, DN_Str8 key, DN_Str8 value);
|
||||
DN_API void DN_JSONBuilder_U64Named (DN_JSONBuilder *builder, DN_Str8 key, uint64_t value);
|
||||
DN_API void DN_JSONBuilder_I64Named (DN_JSONBuilder *builder, DN_Str8 key, int64_t value);
|
||||
DN_API void DN_JSONBuilder_F64Named (DN_JSONBuilder *builder, DN_Str8 key, double value, int decimal_places);
|
||||
DN_API void DN_JSONBuilder_BoolNamed (DN_JSONBuilder *builder, DN_Str8 key, bool value);
|
||||
|
||||
#define DN_JSONBuilder_ObjectBegin(builder) DN_JSONBuilder_ObjectBeginNamed(builder, DN_Str8Lit(""))
|
||||
#define DN_JSONBuilder_ArrayBegin(builder) DN_JSONBuilder_ArrayBeginNamed(builder, DN_Str8Lit(""))
|
||||
#define DN_JSONBuilder_Str8(builder, value) DN_JSONBuilder_Str8Named(builder, DN_Str8Lit(""), value)
|
||||
#define DN_JSONBuilder_Literal(builder, value) DN_JSONBuilder_LiteralNamed(builder, DN_Str8Lit(""), value)
|
||||
#define DN_JSONBuilder_U64(builder, value) DN_JSONBuilder_U64Named(builder, DN_Str8Lit(""), value)
|
||||
#define DN_JSONBuilder_I64(builder, value) DN_JSONBuilder_I64Named(builder, DN_Str8Lit(""), value)
|
||||
#define DN_JSONBuilder_F64(builder, value) DN_JSONBuilder_F64Named(builder, DN_Str8Lit(""), value)
|
||||
#define DN_JSONBuilder_Bool(builder, value) DN_JSONBuilder_BoolNamed(builder, DN_Str8Lit(""), value)
|
||||
#endif // !defined(DN_NO_JSON_BUILDER)
|
||||
|
||||
// NOTE: DN_BinarySearch
|
||||
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);
|
||||
|
||||
// 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
|
||||
template <typename T>
|
||||
bool DN_BinarySearch_DefaultLessThan(T const &lhs, T const &rhs)
|
||||
{
|
||||
bool result = lhs < rhs;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DN_BinarySearchResult DN_BinarySearch(T const *array,
|
||||
DN_USize array_size,
|
||||
T const &find,
|
||||
DN_BinarySearchType type,
|
||||
DN_BinarySearchLessThanProc<T> less_than)
|
||||
{
|
||||
DN_BinarySearchResult result = {};
|
||||
if (!array || array_size <= 0 || !less_than)
|
||||
return result;
|
||||
|
||||
T const *end = array + array_size;
|
||||
T const *first = array;
|
||||
T const *last = end;
|
||||
while (first != last) {
|
||||
DN_USize count = last - first;
|
||||
T const *it = first + (count / 2);
|
||||
|
||||
bool advance_first = false;
|
||||
if (type == DN_BinarySearchType_UpperBound)
|
||||
advance_first = !less_than(find, it[0]);
|
||||
else
|
||||
advance_first = less_than(it[0], find);
|
||||
|
||||
if (advance_first)
|
||||
first = it + 1;
|
||||
else
|
||||
last = it;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case DN_BinarySearchType_Match: {
|
||||
result.found = first != end && !less_than(find, *first);
|
||||
} break;
|
||||
|
||||
case DN_BinarySearchType_LowerBound: /*FALLTHRU*/
|
||||
case DN_BinarySearchType_UpperBound: {
|
||||
result.found = first != end;
|
||||
} break;
|
||||
}
|
||||
|
||||
result.index = first - array;
|
||||
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)
|
||||
@@ -1250,10 +1250,10 @@ DN_API void DN_ArenaUAFCheck(DN_Arena *arena)
|
||||
(void)arena;
|
||||
#if DN_ARENA_TEMP_MEM_UAF_GUARD
|
||||
DN_MemList *mem = arena->mem;
|
||||
if (!mem)
|
||||
if (!arena || !mem)
|
||||
return;
|
||||
|
||||
if (arena->uaf_guard_temp_mem && !arena->uaf_guard_is_being_checked) {
|
||||
if ((arena->uaf_guard_temp_mem || mem->uaf_guard_active_temp_mem) && !arena->uaf_guard_is_being_checked) {
|
||||
// NOTE: The following functions below allocate memory which might trigger an additional UAF
|
||||
// check which would cause infinite recursion so we set a flag here to prevent that.
|
||||
arena->uaf_guard_is_being_checked = true;
|
||||
@@ -1278,7 +1278,11 @@ DN_API void DN_ArenaUAFCheck(DN_Arena *arena)
|
||||
arena);
|
||||
|
||||
if (DN_MemListUAFTracingEnabled_(mem)) {
|
||||
DN_Str8 curr_stack_trace = DN_Str8PadNewLines(DN_StackTraceWalkResultToStr8(arena, &arena->uaf_guard_temp_mem->trace, 1), DN_Str8Lit(" "), arena);
|
||||
DN_Str8 curr_stack_trace = DN_Str8Lit("<Unknown: Arena is not using temporary memory>");
|
||||
if (arena->uaf_guard_temp_mem)
|
||||
curr_stack_trace = DN_StackTraceWalkResultToStr8(arena, &arena->uaf_guard_temp_mem->trace, 1);
|
||||
curr_stack_trace = DN_Str8PadNewLines(curr_stack_trace, DN_Str8Lit(" "), arena);
|
||||
|
||||
DN_Str8 active_stack_trace = DN_Str8PadNewLines(DN_StackTraceWalkResultToStr8(arena, &mem->uaf_guard_active_temp_mem->trace, 1), DN_Str8Lit(" "), arena);
|
||||
DN_AssertF(mem->uaf_guard_active_id == arena->uaf_guard_id,
|
||||
"%.*s\n\nThe originating temporary memory region (id: %'u) was created at:"
|
||||
@@ -1316,7 +1320,7 @@ DN_API DN_Arena DN_ArenaTempBeginFromMemList(DN_MemList* mem)
|
||||
temp_mem.trace = DN_StackTraceWalk(&result, 256);
|
||||
|
||||
// NOTE: Create persistent temp mem and set it on the mem list
|
||||
result.uaf_guard_temp_mem = DN_ArenaNewCopy(&result, DN_MemListTemp, &temp_mem);
|
||||
result.uaf_guard_temp_mem = DN_MemListNewCopy(mem, DN_MemListTemp, &temp_mem);
|
||||
result.uaf_guard_prev_temp_mem = mem->uaf_guard_active_temp_mem;
|
||||
mem->uaf_guard_active_temp_mem = result.uaf_guard_temp_mem;
|
||||
|
||||
@@ -5004,7 +5008,7 @@ DN_API DN_LogPrefixSize DN_LogMakePrefix(DN_LogStyle style, DN_LogTypeParam type
|
||||
"%.*s" // type padding
|
||||
"%.*s" // reset
|
||||
" %.*s" // file name
|
||||
":%05I32u " // line number
|
||||
":%05u " // line number
|
||||
,
|
||||
date.year,
|
||||
date.month,
|
||||
|
||||
@@ -156,6 +156,13 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
||||
DN_Assert(req->response.state >= DN_NETResponseState_WSOpen && req->response.state <= DN_NETResponseState_WSPong);
|
||||
req->response.state = DN_NETResponseState_WSOpen;
|
||||
|
||||
// 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
|
||||
// payload
|
||||
DN_NET_EndFinishedRequest_(req);
|
||||
req->start_response_arena = DN_ArenaTempBeginFromArena(&req->arena);
|
||||
curl_req->str8_builder = DN_Str8BuilderFromArena(&req->start_response_arena);
|
||||
|
||||
for (DN_OS_MutexScope(&curl->list_mutex)) {
|
||||
DN_Assert(DN_NET_CurlRequestIsInList(curl->request_list, req));
|
||||
DN_DoublyLLDetach(curl->request_list, req);
|
||||
@@ -168,7 +175,7 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
||||
DN_NETRequest *request = DN_Cast(DN_NETRequest *) event.request.handle;
|
||||
|
||||
// NOTE: Release resources
|
||||
DN_ArenaTempEnd(&request->arena, DN_ArenaReset_Yes);
|
||||
DN_NET_EndFinishedRequest_(request);
|
||||
DN_OS_SemaphoreDeinit(&request->completion_sem);
|
||||
|
||||
curl_multi_remove_handle(curl->thread_curlm, curl_req->handle);
|
||||
@@ -177,8 +184,8 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
||||
|
||||
// NOTE: Zero the struct preserving just the data we need to retain
|
||||
DN_NETRequest resetter = {};
|
||||
resetter.arena = request->arena;
|
||||
resetter.gen = request->gen;
|
||||
resetter.arena = request->arena;
|
||||
resetter.gen = request->gen;
|
||||
DN_Memcpy(resetter.context, request->context, sizeof(resetter.context));
|
||||
*request = resetter;
|
||||
|
||||
@@ -302,7 +309,7 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
||||
|
||||
// NOTE: Allocate and read (we use meta->bytesleft as per comment from initial recv)
|
||||
if (meta->bytesleft) {
|
||||
DN_Str8 buffer = DN_Str8AllocArena(meta->bytesleft, DN_ZMem_No, &req->arena);
|
||||
DN_Str8 buffer = DN_Str8AllocArena(meta->bytesleft, DN_ZMem_No, &req->start_response_arena);
|
||||
DN_Assert(buffer.size == DN_Cast(DN_USize)meta->bytesleft);
|
||||
receive_result = curl_ws_recv(curl_req->handle, buffer.data, buffer.size, &buffer.size, &meta);
|
||||
DN_Assert(buffer.size == DN_Cast(DN_USize)meta->len);
|
||||
@@ -352,7 +359,7 @@ static int32_t DN_NET_CurlThreadEntryPoint_(DN_OSThread *thread)
|
||||
} else if (receive_result != CURLE_OK) {
|
||||
DN_USize curl_extended_error_size = DN_CStr8Size(curl_req->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,
|
||||
"Websocket receive '%.*s' failed (CURL %d): %s%s%s%s",
|
||||
DN_Str8PrintFmt(req->url),
|
||||
receive_result,
|
||||
@@ -583,15 +590,13 @@ void DN_NET_CurlDoWSSend(DN_NETRequestHandle handle, DN_Str8 payload, DN_NETWSSe
|
||||
static DN_NETResponse DN_NET_CurlHandleFinishedRequest_(DN_NETCurlCore *curl, DN_NETRequest *req, DN_Arena *arena)
|
||||
{
|
||||
// NOTE: Generate the response, copy out the strings into the user given memory
|
||||
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);
|
||||
if (result.error_str8.size)
|
||||
result.error_str8 = DN_Str8FromStr8Arena(result.error_str8, arena);
|
||||
curl_req->str8_builder = {}; // Clear it out, reinitialised on subsequent do request call
|
||||
}
|
||||
DN_NET_EndFinishedRequest_(req);
|
||||
|
||||
bool continue_ws_request = false;
|
||||
if (req->type == DN_NETRequestType_WS &&
|
||||
@@ -618,6 +623,7 @@ static DN_NETResponse DN_NET_CurlHandleFinishedRequest_(DN_NETCurlCore *curl, DN
|
||||
DN_DoublyLLAppend(curl->deinit_list, req);
|
||||
}
|
||||
|
||||
|
||||
// NOTE: Submit the post-request event to the CURL thread
|
||||
DN_NETCurlRingEvent event = {};
|
||||
event.request = DN_NET_HandleFromRequest(req);
|
||||
|
||||
@@ -97,7 +97,7 @@ static bool DN_NET_EmcWSOnMessage(int eventType, const EmscriptenWebSocketMessag
|
||||
DN_NETEmcWSEvent *net_event = DN_NET_EmcAllocWSEvent_(req);
|
||||
net_event->state = event->isText ? DN_NETResponseState_WSText : DN_NETResponseState_WSBinary;
|
||||
if (event->numBytes > 0)
|
||||
net_event->payload = DN_Str8FromPtrArena(&req->arena, event->data, event->numBytes);
|
||||
net_event->payload = DN_Str8FromPtrArena(event->data, event->numBytes, &req->arena);
|
||||
DN_NET_EmcOnRequestDone_(net, req);
|
||||
return true;
|
||||
}
|
||||
@@ -129,7 +129,7 @@ static void DN_NET_EmcHTTPSuccessCallback(emscripten_fetch_t *fetch)
|
||||
DN_NETCore *net = DN_Cast(DN_NETCore *) req->context[0];
|
||||
req->response.http_status = fetch->status;
|
||||
req->response.state = DN_NETResponseState_HTTP;
|
||||
req->response.body = DN_Str8FromStr8Arena(&req->arena, DN_Str8FromPtr(fetch->data, fetch->numBytes - 1));
|
||||
req->response.body = DN_Str8FromStr8Arena(DN_Str8FromPtr(fetch->data, fetch->numBytes - 1), &req->arena);
|
||||
DN_NET_EmcOnRequestDone_(net, req);
|
||||
}
|
||||
|
||||
@@ -176,8 +176,9 @@ static DN_NETRequest *DN_NET_EmcAllocRequest_(DN_NETCore *net)
|
||||
// NOTE: Setup the request's arena here. WASM doesn't have the concept of virtual memory
|
||||
// so we use malloc to initialise it.
|
||||
result = DN_ArenaNew(&net->arena, DN_NETRequest, DN_ZMem_Yes);
|
||||
if (result)
|
||||
result->arena = DN_ArenaFromHeap(DN_Megabytes(1), DN_ArenaFlags_Nil);
|
||||
if (result) {
|
||||
result->arena = DN_ArenaFromMemList(&result->mem);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Setup some emscripten specific data into our request context
|
||||
@@ -210,7 +211,7 @@ DN_NETRequestHandle DN_NET_EmcDoHTTP(DN_NETCore *net, DN_Str8 url, DN_Str8 metho
|
||||
|
||||
// NOTE: Assign HTTP headers
|
||||
if (req->args.headers_size) {
|
||||
char **headers = DN_ArenaNewArray(&req->arena, char *, req->args.headers_size + 1, DN_ZMem_Yes);
|
||||
char **headers = DN_ArenaNewArray(&req->start_response_arena, char *, req->args.headers_size + 1, DN_ZMem_Yes);
|
||||
for (DN_ForItSize(it, DN_Str8, req->args.headers, req->args.headers_size)) {
|
||||
DN_Assert(it.data->data[it.data->size] == 0);
|
||||
headers[it.index] = it.data->data;
|
||||
@@ -244,9 +245,6 @@ DN_NETRequestHandle DN_NET_EmcDoHTTP(DN_NETCore *net, DN_Str8 url, DN_Str8 metho
|
||||
fetch_attribs.userData = req;
|
||||
}
|
||||
|
||||
// NOTE: Update the pop to position for the request
|
||||
req->start_response_arena_pos = DN_ArenaPos(&req->arena);
|
||||
|
||||
// NOTE: Dispatch the asynchronous fetch
|
||||
emscripten_fetch(&fetch_attribs, req->url.data);
|
||||
return result;
|
||||
@@ -261,8 +259,7 @@ DN_NETRequestHandle DN_NET_EmcDoWS(DN_NETCore *net, DN_Str8 url)
|
||||
return result;
|
||||
|
||||
// NOTE: Setup some emscripten specific data into our request context
|
||||
req->context[1] = DN_Cast(DN_UPtr) DN_ArenaNew(&req->arena, DN_NETEmcRequest, DN_ZMem_Yes);
|
||||
req->start_response_arena_pos = DN_ArenaPos(&req->arena);
|
||||
req->context[1] = DN_Cast(DN_UPtr) DN_ArenaNew(&req->start_response_arena, DN_NETEmcRequest, DN_ZMem_Yes);
|
||||
|
||||
// NOTE: Create the websocket request and dispatch it via emscripten
|
||||
EmscriptenWebSocketCreateAttributes attr;
|
||||
@@ -293,10 +290,10 @@ void DN_NET_EmcDoWSSend(DN_NETRequestHandle handle, DN_Str8 data, DN_NETWSSend s
|
||||
switch (send) {
|
||||
default: DN_InvalidCodePath; break;
|
||||
case DN_NETWSSend_Text: {
|
||||
DN_U64 pos = DN_ArenaPos(&request_ptr->arena);
|
||||
DN_Str8 data_null_terminated = DN_Str8FromStr8Arena(&request_ptr->arena, data);
|
||||
DN_U64 pos = DN_MemListPos(request_ptr->start_response_arena.mem);
|
||||
DN_Str8 data_null_terminated = DN_Str8FromStr8Arena(data, &request_ptr->start_response_arena);
|
||||
result = emscripten_websocket_send_utf8_text(emc_request->socket, data_null_terminated.data);
|
||||
DN_ArenaPopTo(&request_ptr->arena, pos);
|
||||
DN_MemListPopTo(request_ptr->arena.mem, pos);
|
||||
} break;
|
||||
|
||||
case DN_NETWSSend_Binary: {
|
||||
@@ -320,7 +317,7 @@ static DN_NETResponse DN_NET_EmcHandleFinishedRequest_(DN_NETCore *net, DN_NETEm
|
||||
bool end_request = true;
|
||||
bool dequeue_request = true;
|
||||
if (request->type == DN_NETRequestType_HTTP) {
|
||||
result.body = DN_Str8FromStr8Arena(arena, result.body);
|
||||
result.body = DN_Str8FromStr8Arena(result.body, arena);
|
||||
} else {
|
||||
// NOTE: Get emscripten contexts
|
||||
DN_NETEmcWSEvent *emc_event = emc_request->first_event;
|
||||
@@ -332,7 +329,7 @@ static DN_NETResponse DN_NET_EmcHandleFinishedRequest_(DN_NETCore *net, DN_NETEm
|
||||
// NOTE: Build the result
|
||||
result.state = emc_event->state;
|
||||
result.request = handle;
|
||||
result.body = DN_Str8FromStr8Arena(arena, emc_event->payload);
|
||||
result.body = DN_Str8FromStr8Arena(emc_event->payload, arena);
|
||||
|
||||
// NOTE: Advance the event list
|
||||
{
|
||||
@@ -374,10 +371,8 @@ static DN_NETResponse DN_NET_EmcHandleFinishedRequest_(DN_NETCore *net, DN_NETEm
|
||||
|
||||
// NOTE: Deallocate the memory used in the request and reset the string builder (as all
|
||||
// payload(s) have been read from the request).
|
||||
if (end_request)
|
||||
DN_ArenaPopTo(&request->arena, 0);
|
||||
else
|
||||
DN_ArenaPopTo(&request->arena, request->start_response_arena_pos);
|
||||
if (!end_request)
|
||||
DN_ArenaTempEnd(&request->start_response_arena, DN_ArenaReset_Yes);
|
||||
}
|
||||
|
||||
if (end_request) {
|
||||
|
||||
@@ -449,11 +449,11 @@ static DN_UTCore DN_TST_BaseArena()
|
||||
// NOTE: Allocate 128 kilobytes, fill it with garbage, then reset the arena
|
||||
uintptr_t first_ptr_address = 0;
|
||||
{
|
||||
DN_Arena temp_mem = DN_ArenaTempBeginFromArena(&arena);
|
||||
void *ptr = DN_ArenaAlloc(&arena, alloc_size, alignment, DN_ZMem_Yes);
|
||||
DN_U64 mem_p = DN_MemListPos(arena.mem);
|
||||
void *ptr = DN_ArenaAlloc(&arena, alloc_size, alignment, DN_ZMem_Yes);
|
||||
first_ptr_address = DN_Cast(uintptr_t) ptr;
|
||||
DN_Memset(ptr, 'z', alloc_size);
|
||||
DN_ArenaTempEnd(&temp_mem, DN_ArenaReset_Yes);
|
||||
DN_MemListPopTo(arena.mem, mem_p);
|
||||
}
|
||||
|
||||
// NOTE: Reallocate 128 kilobytes
|
||||
@@ -499,9 +499,9 @@ static DN_UTCore DN_TST_BaseArena()
|
||||
char *ptr_1mb = DN_Cast(char *) DN_ArenaAlloc(&arena, DN_Megabytes(1), 1 /*align*/, DN_ZMem_Yes);
|
||||
DN_UT_Assert(&result, ptr_1mb);
|
||||
|
||||
DN_Arena temp_memory = DN_ArenaTempBeginFromArena(&arena);
|
||||
DN_Arena temp = DN_ArenaTempBeginFromArena(&arena);
|
||||
{
|
||||
char *ptr_4mb = DN_ArenaNewArray(&arena, char, DN_Megabytes(4), DN_ZMem_Yes);
|
||||
char *ptr_4mb = DN_ArenaNewArray(&temp, char, DN_Megabytes(4), DN_ZMem_Yes);
|
||||
DN_UT_Assert(&result, ptr_4mb);
|
||||
|
||||
DN_MemBlock const *block_4mb_begin = arena.mem->curr;
|
||||
@@ -514,7 +514,7 @@ static DN_UTCore DN_TST_BaseArena()
|
||||
DN_UT_AssertF(&result, ptr_1mb >= DN_Cast(char *) block_1mb_begin && ptr_1mb <= block_1mb_end, "Pointer was not allocated from correct memory block");
|
||||
DN_UT_AssertF(&result, ptr_4mb >= DN_Cast(char *) block_4mb_begin && ptr_4mb <= block_4mb_end, "Pointer was not allocated from correct memory block");
|
||||
}
|
||||
DN_ArenaTempEnd(&temp_memory, DN_ArenaReset_Yes);
|
||||
DN_ArenaTempEnd(&temp, DN_ArenaReset_Yes);
|
||||
DN_UT_Assert(&result, arena.mem->curr->prev == nullptr);
|
||||
DN_UT_AssertF(&result,
|
||||
arena.mem->curr->reserve >= DN_Megabytes(1),
|
||||
|
||||
+42
-46
@@ -228,20 +228,16 @@ DN_API bool DN_OS_SetEnvVar(DN_Str8 name, DN_Str8 value)
|
||||
|
||||
DN_API DN_OSDiskSpace DN_OS_DiskSpace(DN_Str8 path)
|
||||
{
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_OSDiskSpace result = {};
|
||||
DN_Str8 path_z_terminated = DN_Str8FromStr8Arena(tmem.arena, path);
|
||||
|
||||
struct statvfs info = {};
|
||||
if (statvfs(path_z_terminated.data, &info) != 0) {
|
||||
DN_TCScratchEnd(&tmem);
|
||||
return result;
|
||||
DN_Str8 path_z_terminated = DN_Str8FromStr8Arena(path, &scratch.arena);
|
||||
struct statvfs info = {};
|
||||
if (statvfs(path_z_terminated.data, &info) == 0) {
|
||||
result.success = true;
|
||||
result.avail = info.f_bavail * info.f_frsize;
|
||||
result.size = info.f_blocks * info.f_frsize;
|
||||
}
|
||||
|
||||
result.success = true;
|
||||
result.avail = info.f_bavail * info.f_frsize;
|
||||
result.size = info.f_blocks * info.f_frsize;
|
||||
DN_TCScratchEnd(&tmem);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -251,11 +247,11 @@ DN_API DN_Str8 DN_OS_EXEPath(DN_Arena *arena)
|
||||
if (!arena)
|
||||
return result;
|
||||
|
||||
int required_size_wo_null_terminator = 0;
|
||||
DN_U64 mem_p = DN_MemListPos(arena->mem);
|
||||
int required_size_wo_null_terminator = 0;
|
||||
for (int try_size = 128;; try_size *= 2) {
|
||||
auto scoped_arena = DN_ArenaTempMemScope(arena);
|
||||
char *try_buf = DN_ArenaNewArray(arena, char, try_size, DN_ZMem_No);
|
||||
int bytes_written = readlink("/proc/self/exe", try_buf, try_size);
|
||||
char *try_buf = DN_ArenaNewArray(arena, char, try_size, DN_ZMem_No);
|
||||
int bytes_written = readlink("/proc/self/exe", try_buf, try_size);
|
||||
if (bytes_written == -1) {
|
||||
// Failed, we're unable to determine the executable directory
|
||||
break;
|
||||
@@ -280,11 +276,11 @@ DN_API DN_Str8 DN_OS_EXEPath(DN_Arena *arena)
|
||||
break;
|
||||
}
|
||||
}
|
||||
DN_MemListPopTo(arena->mem, mem_p);
|
||||
|
||||
if (required_size_wo_null_terminator) {
|
||||
DN_ArenaTempMem temp_mem = DN_ArenaTempMemBegin(arena);
|
||||
char *exe_path =
|
||||
DN_ArenaNewArray(arena, char, required_size_wo_null_terminator + 1, DN_ZMem_No);
|
||||
mem_p = DN_MemListPos(arena->mem);
|
||||
char *exe_path = DN_ArenaNewArray(arena, char, required_size_wo_null_terminator + 1, DN_ZMem_No);
|
||||
exe_path[required_size_wo_null_terminator] = 0;
|
||||
|
||||
int bytes_written = readlink("/proc/self/exe", exe_path, required_size_wo_null_terminator);
|
||||
@@ -292,7 +288,7 @@ DN_API DN_Str8 DN_OS_EXEPath(DN_Arena *arena)
|
||||
// Note that if read-link fails again can be because there's
|
||||
// a potential race condition here, our exe or directory could have
|
||||
// been deleted since the last call, so we need to be careful.
|
||||
DN_ArenaTempMemEnd(temp_mem);
|
||||
DN_MemListPopTo(arena->mem, mem_p);
|
||||
} else {
|
||||
result = DN_Str8FromPtr(exe_path, required_size_wo_null_terminator);
|
||||
}
|
||||
@@ -631,15 +627,15 @@ DN_API bool DN_OS_PathIsDir(DN_Str8 path)
|
||||
|
||||
DN_API bool DN_OS_PathMakeDir(DN_Str8 path)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
bool result = true;
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
bool result = true;
|
||||
|
||||
// TODO(doyle): Implement this without using the path indexes, it's not
|
||||
// necessary. See Windows implementation.
|
||||
DN_USize path_indexes_size = 0;
|
||||
uint16_t path_indexes[64] = {};
|
||||
|
||||
DN_Str8 copy = DN_Str8FromStr8Arena(scratch.arena, path);
|
||||
DN_Str8 copy = DN_Str8FromStr8Arena(path, &scratch.arena);
|
||||
for (DN_USize index = copy.size - 1; index < copy.size; index--) {
|
||||
bool first_char = index == (copy.size - 1);
|
||||
char ch = copy.data[index];
|
||||
@@ -674,8 +670,8 @@ DN_API bool DN_OS_PathMakeDir(DN_Str8 path)
|
||||
}
|
||||
|
||||
for (DN_USize index = path_indexes_size - 1; result && index < path_indexes_size; index--) {
|
||||
uint16_t path_index = path_indexes[index];
|
||||
char temp = copy.data[path_index];
|
||||
DN_U16 path_index = path_indexes[index];
|
||||
char temp = copy.data[path_index];
|
||||
|
||||
if (index != 0)
|
||||
copy.data[path_index] = 0;
|
||||
@@ -800,7 +796,7 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle,
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
|
||||
if (arena && handle.stdout_read) {
|
||||
char buffer[4096];
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(scratch.arena);
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
|
||||
for (;;) {
|
||||
ssize_t bytes_read =
|
||||
read(stdout_pipe[DN_OSPipeType__Read], buffer, sizeof(buffer));
|
||||
@@ -814,7 +810,7 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle,
|
||||
|
||||
if (arena && handle.stderr_read) {
|
||||
char buffer[4096];
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(scratch.arena);
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
|
||||
for (;;) {
|
||||
ssize_t bytes_read =
|
||||
read(stderr_pipe[DN_OSPipeType__Read], buffer, sizeof(buffer));
|
||||
@@ -848,7 +844,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line,
|
||||
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_DEFER { DN_TCScratchEnd(&scratch); };
|
||||
DN_Str8 cmd_rendered = DN_Str8SliceRender(cmd_line, DN_Str8Lit(" "), scratch.arena);
|
||||
DN_Str8 cmd_rendered = DN_Str8SliceRender(cmd_line, DN_Str8Lit(" "), &scratch.arena);
|
||||
int stdout_pipe[DN_OSPipeType__Count] = {};
|
||||
int stderr_pipe[DN_OSPipeType__Count] = {};
|
||||
|
||||
@@ -942,7 +938,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line,
|
||||
|
||||
// NOTE: Convert the command into something suitable for execvp
|
||||
char **argv =
|
||||
DN_ArenaNewArray(scratch.arena, char *, cmd_line.count + 1 /*null*/, DN_ZMem_Yes);
|
||||
DN_ArenaNewArray(&scratch.arena, char *, cmd_line.count + 1 /*null*/, DN_ZMem_Yes);
|
||||
if (!argv) {
|
||||
result.exit_code = -1;
|
||||
DN_ErrSinkAppendF(
|
||||
@@ -955,7 +951,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line,
|
||||
|
||||
for (DN_ForIndexU(arg_index, cmd_line.count)) {
|
||||
DN_Str8 arg = cmd_line.data[arg_index];
|
||||
argv[arg_index] = DN_Str8FromStr8Arena(scratch.arena, arg).data; // NOTE: Copy string to guarantee it is null-terminated
|
||||
argv[arg_index] = DN_Str8FromStr8Arena(arg, &scratch.arena).data; // NOTE: Copy string to guarantee it is null-terminated
|
||||
}
|
||||
|
||||
// NOTE: Change the working directory if there is one
|
||||
@@ -973,7 +969,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line,
|
||||
|
||||
if (args->working_dir.size) {
|
||||
prev_working_dir = get_current_dir_name();
|
||||
DN_Str8 working_dir = DN_Str8FromStr8Arena(scratch.arena, args->working_dir);
|
||||
DN_Str8 working_dir = DN_Str8FromStr8Arena(args->working_dir, &scratch.arena);
|
||||
if (chdir(working_dir.data) == -1) {
|
||||
result.os_error_code = errno;
|
||||
DN_ErrSinkAppendF(
|
||||
@@ -1374,11 +1370,11 @@ DN_API void DN_OS_PosixThreadSetName(DN_Str8 name)
|
||||
#if defined(DN_PLATFORM_EMSCRIPTEN)
|
||||
(void)name;
|
||||
#else
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8 copy = DN_Str8FromStr8Arena(tmem.arena, name);
|
||||
pthread_t thread = pthread_self();
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8 copy = DN_Str8FromStr8Arena(name, &scratch.arena);
|
||||
pthread_t thread = pthread_self();
|
||||
pthread_setname_np(thread, (char *)copy.data);
|
||||
DN_TCScratchEnd(&tmem);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1398,9 +1394,9 @@ DN_API DN_OSPosixProcSelfStatus DN_OS_PosixProcSelfStatus()
|
||||
DN_OSFile file = DN_OS_FileOpen(DN_Str8Lit("/proc/self/status"), DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_Read, nullptr);
|
||||
|
||||
if (!file.error) {
|
||||
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
char buf[256];
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(tmem.arena);
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
|
||||
for (;;) {
|
||||
DN_OSFileRead read = DN_OS_FileRead(&file, buf, sizeof(buf), nullptr);
|
||||
if (!read.success || read.bytes_read == 0)
|
||||
@@ -1412,8 +1408,8 @@ DN_API DN_OSPosixProcSelfStatus DN_OS_PosixProcSelfStatus()
|
||||
DN_Str8 const PID = DN_Str8Lit("Pid:");
|
||||
DN_Str8 const VM_PEAK = DN_Str8Lit("VmPeak:");
|
||||
DN_Str8 const VM_SIZE = DN_Str8Lit("VmSize:");
|
||||
DN_Str8 status_buf = DN_Str8BuilderBuild(&builder, tmem.arena);
|
||||
DN_Str8SplitResult lines = DN_Str8SplitArena(tmem.arena, status_buf, DN_Str8Lit("\n"), DN_Str8SplitIncludeEmptyStrings_No);
|
||||
DN_Str8 status_buf = DN_Str8BuilderBuild(&builder, &scratch.arena);
|
||||
DN_Str8SplitResult lines = DN_Str8SplitArena(status_buf, DN_Str8Lit("\n"), DN_Str8SplitFlags_ExcludeEmptyStrings, &scratch.arena);
|
||||
|
||||
for (DN_ForItSize(line_it, DN_Str8, lines.data, lines.count)) {
|
||||
DN_Str8 line = DN_Str8TrimWhitespaceAround(*line_it.data);
|
||||
@@ -1442,7 +1438,7 @@ DN_API DN_OSPosixProcSelfStatus DN_OS_PosixProcSelfStatus()
|
||||
DN_Assert(to_u64.success);
|
||||
}
|
||||
}
|
||||
DN_TCScratchEnd(&tmem);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
DN_OS_FileClose(&file);
|
||||
return result;
|
||||
@@ -1499,7 +1495,7 @@ static void DN_OS_HttpRequestEMFetchOnSuccessCallback(emscripten_fetch_t *fetch)
|
||||
return;
|
||||
|
||||
response->http_status = DN_Cast(DN_U32) fetch->status;
|
||||
response->body = DN_Str8AllocArena(response->arena, fetch->numBytes, DN_ZMem_No);
|
||||
response->body = DN_Str8AllocArena(fetch->numBytes, DN_ZMem_No, response->arena);
|
||||
if (response->body.data)
|
||||
DN_Memcpy(response->body.data, fetch->data, fetch->numBytes);
|
||||
|
||||
@@ -1514,7 +1510,7 @@ static void DN_OS_HttpRequestEMFetchOnErrorCallback(emscripten_fetch_t *fetch)
|
||||
return;
|
||||
|
||||
response->http_status = DN_Cast(DN_U32) fetch->status;
|
||||
response->body = DN_Str8AllocArena(response->arena, fetch->numBytes, DN_ZMem_No);
|
||||
response->body = DN_Str8AllocArena(fetch->numBytes, DN_ZMem_No, response->arena);
|
||||
if (response->body.size)
|
||||
DN_Memcpy(response->body.data, fetch->data, fetch->numBytes);
|
||||
|
||||
@@ -1536,13 +1532,13 @@ DN_API void DN_OS_HttpRequestAsync(DN_OSHttpResponse *response,
|
||||
return;
|
||||
|
||||
response->arena = arena;
|
||||
response->builder.arena = response->scratch_arena ? response->scratch_arena : &response->tmp_arena;
|
||||
response->builder.arena = response->scratch_arena.mem ? &response->scratch_arena : &response->tmp_arena;
|
||||
|
||||
DN_Arena *scratch = response->scratch_arena;
|
||||
DN_Arena *scratch = &response->scratch_arena;
|
||||
DN_TCScratch scratch_ = DN_TCScratchBegin(&arena, 1);
|
||||
DN_DEFER { DN_TCScratchEnd(&scratch_); };
|
||||
if (!scratch)
|
||||
scratch = scratch_.arena;
|
||||
scratch = &scratch_.arena;
|
||||
|
||||
#if defined(DN_PLATFORM_EMSCRIPTEN)
|
||||
emscripten_fetch_attr_t fetch_attribs = {};
|
||||
@@ -1594,7 +1590,7 @@ DN_API void DN_OS_HttpRequestFree(DN_OSHttpResponse *response)
|
||||
}
|
||||
#endif // #elif defined(DN_OS_WIN32)
|
||||
|
||||
DN_ArenaDeinit(&response->tmp_arena);
|
||||
DN_MemListDeinit(response->tmp_arena.mem);
|
||||
DN_OS_SemaphoreDeinit(&response->on_complete_semaphore);
|
||||
*response = {};
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#if (_CLANGD)
|
||||
#if defined(_CLANGD)
|
||||
#define DN_H_WITH_OS 1
|
||||
#include "dn.h"
|
||||
#endif
|
||||
|
||||
@@ -39,7 +39,7 @@ pushd %build_dir%
|
||||
|
||||
where /q emcc && (
|
||||
echo [BUILD] Emscripten emcc detected, compiling ...
|
||||
call emcc -g -msimd128 -msse2 %flags% -o %build_dir%\dn_unit_tests_emcc.js -s FETCH=1 -pthread -s ASYNCIFY=1 -lwebsocket -Wall || echo Failed&& exit /b 1
|
||||
call emcc -g -msimd128 -msse2 %flags% -o %build_dir%\dn_unit_tests_emcc.js -s FETCH=1 -pthread -s ASYNCIFY=1 -lwebsocket -Wall || echo EMCC build failed&& exit /b 1
|
||||
)
|
||||
|
||||
where /q cl && (
|
||||
|
||||
@@ -35,14 +35,11 @@ static void AppendCppFileLineByLine(DN_Str8Builder *dest, DN_Str8 cpp_path)
|
||||
DN_ErrSinkEndExitIfErrorF(err, -1, "Failed to load file from '%S' for appending", cpp_path);
|
||||
|
||||
bool inside_clangd_preprocessor_block = false;
|
||||
for (DN_Str8 inc_walker = buffer;;) {
|
||||
DN_Str8BSplitResult split = DN_Str8BSplit(inc_walker, DN_Str8Lit("\n"));
|
||||
if (split.lhs.size == 0)
|
||||
break;
|
||||
inc_walker = split.rhs;
|
||||
|
||||
for (DN_Str8 walker = buffer; walker.size;) {
|
||||
// NOTE: Trim the whitespace, mainly for windows, the file we read will have \r\n whereas we just want to emit \n
|
||||
DN_Str8 line = DN_Str8TrimTailWhitespace(split.lhs);
|
||||
DN_Str8BSplitResult split = DN_Str8BSplit(walker, DN_Str8Lit("\n"));
|
||||
DN_Str8 line = DN_Str8TrimTailWhitespace(split.lhs);
|
||||
walker = split.rhs;
|
||||
|
||||
// NOTE: Detect if we're inside a clangd preprocessor block
|
||||
// TODO: This breaks if there's any nested #if's in the block (we naiively match on #endif)
|
||||
@@ -112,19 +109,17 @@ int main(int argc, char **argv)
|
||||
|
||||
DN_Str8 const REL_FILE_PATHS[] = {
|
||||
DN_Str8Lit("dn"),
|
||||
DN_Str8Lit("Extra/dn_async"),
|
||||
DN_Str8Lit("Extra/dn_bin_pack"),
|
||||
DN_Str8Lit("Extra/dn_csv"),
|
||||
DN_Str8Lit("Extra/dn_helpers"),
|
||||
};
|
||||
|
||||
for (DN_ForIndexU(type, FileType_Count)) {
|
||||
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
|
||||
DN_Str8 suffix = type == FileType_Header ? DN_Str8Lit("h") : DN_Str8Lit("cpp");
|
||||
for (DN_ForItCArray(extra_it, DN_Str8 const, REL_FILE_PATHS)) {
|
||||
DN_Str8 extra_path = DN_OS_PathF(&scratch.arena, "%S/%S.%S", dn_root_dir, *extra_it.data, suffix);
|
||||
AppendCppFileLineByLine(&builder, extra_path);
|
||||
for (DN_ForItCArray(it, DN_Str8 const, REL_FILE_PATHS)) {
|
||||
DN_Str8 path = DN_OS_PathF(&scratch.arena, "%S/%S.%S", dn_root_dir, *it.data, suffix);
|
||||
AppendCppFileLineByLine(&builder, path);
|
||||
}
|
||||
|
||||
DN_Date date = DN_OS_DateLocalTimeNow();
|
||||
|
||||
Reference in New Issue
Block a user