Fix emcc, msvc and clang builds

This commit is contained in:
2026-05-18 12:42:51 +10:00
parent 0905a10f61
commit 70ceb6af11
10 changed files with 17582 additions and 427 deletions
File diff suppressed because it is too large Load Diff
+1 -321
View File
@@ -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) #if !defined(DN_H)
#define DN_H #define DN_H
@@ -7529,62 +7529,6 @@ void DN_NET_EndFinishedRequest_ (DN_NETRequest *request);
#endif // DN_NET_H #endif // DN_NET_H
#endif #endif
#endif // !defined(DN_H) #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) #if !defined(DN_BIN_PACK_H)
#define 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); bool DN_CSV_PackNewLine (DN_CSVPack *pack, DN_CSVSerialise serialise);
#endif // !defined(DN_CSV_H) #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)
+9 -5
View File
@@ -1250,10 +1250,10 @@ DN_API void DN_ArenaUAFCheck(DN_Arena *arena)
(void)arena; (void)arena;
#if DN_ARENA_TEMP_MEM_UAF_GUARD #if DN_ARENA_TEMP_MEM_UAF_GUARD
DN_MemList *mem = arena->mem; DN_MemList *mem = arena->mem;
if (!mem) if (!arena || !mem)
return; 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 // 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. // check which would cause infinite recursion so we set a flag here to prevent that.
arena->uaf_guard_is_being_checked = true; arena->uaf_guard_is_being_checked = true;
@@ -1278,7 +1278,11 @@ DN_API void DN_ArenaUAFCheck(DN_Arena *arena)
arena); arena);
if (DN_MemListUAFTracingEnabled_(mem)) { 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_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, DN_AssertF(mem->uaf_guard_active_id == arena->uaf_guard_id,
"%.*s\n\nThe originating temporary memory region (id: %'u) was created at:" "%.*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); temp_mem.trace = DN_StackTraceWalk(&result, 256);
// NOTE: Create persistent temp mem and set it on the mem list // 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; result.uaf_guard_prev_temp_mem = mem->uaf_guard_active_temp_mem;
mem->uaf_guard_active_temp_mem = result.uaf_guard_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" // type padding
"%.*s" // reset "%.*s" // reset
" %.*s" // file name " %.*s" // file name
":%05I32u " // line number ":%05u " // line number
, ,
date.year, date.year,
date.month, date.month,
+12 -6
View File
@@ -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); DN_Assert(req->response.state >= DN_NETResponseState_WSOpen && req->response.state <= DN_NETResponseState_WSPong);
req->response.state = DN_NETResponseState_WSOpen; 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)) { for (DN_OS_MutexScope(&curl->list_mutex)) {
DN_Assert(DN_NET_CurlRequestIsInList(curl->request_list, req)); DN_Assert(DN_NET_CurlRequestIsInList(curl->request_list, req));
DN_DoublyLLDetach(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; DN_NETRequest *request = DN_Cast(DN_NETRequest *) event.request.handle;
// NOTE: Release resources // NOTE: Release resources
DN_ArenaTempEnd(&request->arena, DN_ArenaReset_Yes); 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);
@@ -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) // NOTE: Allocate and read (we use meta->bytesleft as per comment from initial recv)
if (meta->bytesleft) { 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); 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); 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); 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) { } else if (receive_result != CURLE_OK) {
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,
"Websocket receive '%.*s' failed (CURL %d): %s%s%s%s", "Websocket receive '%.*s' failed (CURL %d): %s%s%s%s",
DN_Str8PrintFmt(req->url), DN_Str8PrintFmt(req->url),
receive_result, receive_result,
@@ -584,14 +591,12 @@ static DN_NETResponse DN_NET_CurlHandleFinishedRequest_(DN_NETCurlCore *curl, DN
{ {
// NOTE: Generate the response, copy out the strings into the user given memory // 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); result.body = DN_Str8BuilderBuild(&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);
curl_req->str8_builder = {}; // Clear it out, reinitialised on subsequent do request call
} }
DN_NET_EndFinishedRequest_(req);
bool continue_ws_request = false; bool continue_ws_request = false;
if (req->type == DN_NETRequestType_WS && 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); DN_DoublyLLAppend(curl->deinit_list, req);
} }
// NOTE: Submit the post-request event to the CURL thread // NOTE: Submit the post-request event to the CURL thread
DN_NETCurlRingEvent event = {}; DN_NETCurlRingEvent event = {};
event.request = DN_NET_HandleFromRequest(req); event.request = DN_NET_HandleFromRequest(req);
+14 -19
View File
@@ -97,7 +97,7 @@ static bool DN_NET_EmcWSOnMessage(int eventType, const EmscriptenWebSocketMessag
DN_NETEmcWSEvent *net_event = DN_NET_EmcAllocWSEvent_(req); DN_NETEmcWSEvent *net_event = DN_NET_EmcAllocWSEvent_(req);
net_event->state = event->isText ? DN_NETResponseState_WSText : DN_NETResponseState_WSBinary; net_event->state = event->isText ? DN_NETResponseState_WSText : DN_NETResponseState_WSBinary;
if (event->numBytes > 0) 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); DN_NET_EmcOnRequestDone_(net, req);
return true; 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]; DN_NETCore *net = DN_Cast(DN_NETCore *) req->context[0];
req->response.http_status = fetch->status; req->response.http_status = fetch->status;
req->response.state = DN_NETResponseState_HTTP; 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); 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 // NOTE: Setup the request's arena here. WASM doesn't have the concept of virtual memory
// so we use malloc to initialise it. // so we use malloc to initialise it.
result = DN_ArenaNew(&net->arena, DN_NETRequest, DN_ZMem_Yes); result = DN_ArenaNew(&net->arena, DN_NETRequest, DN_ZMem_Yes);
if (result) if (result) {
result->arena = DN_ArenaFromHeap(DN_Megabytes(1), DN_ArenaFlags_Nil); result->arena = DN_ArenaFromMemList(&result->mem);
}
} }
// NOTE: Setup some emscripten specific data into our request context // 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 // NOTE: Assign HTTP headers
if (req->args.headers_size) { 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)) { for (DN_ForItSize(it, DN_Str8, req->args.headers, req->args.headers_size)) {
DN_Assert(it.data->data[it.data->size] == 0); DN_Assert(it.data->data[it.data->size] == 0);
headers[it.index] = it.data->data; 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; 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 // NOTE: Dispatch the asynchronous fetch
emscripten_fetch(&fetch_attribs, req->url.data); emscripten_fetch(&fetch_attribs, req->url.data);
return result; return result;
@@ -261,8 +259,7 @@ DN_NETRequestHandle DN_NET_EmcDoWS(DN_NETCore *net, DN_Str8 url)
return result; return result;
// NOTE: Setup some emscripten specific data into our request context // 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->context[1] = DN_Cast(DN_UPtr) DN_ArenaNew(&req->start_response_arena, DN_NETEmcRequest, DN_ZMem_Yes);
req->start_response_arena_pos = DN_ArenaPos(&req->arena);
// NOTE: Create the websocket request and dispatch it via emscripten // NOTE: Create the websocket request and dispatch it via emscripten
EmscriptenWebSocketCreateAttributes attr; EmscriptenWebSocketCreateAttributes attr;
@@ -293,10 +290,10 @@ void DN_NET_EmcDoWSSend(DN_NETRequestHandle handle, DN_Str8 data, DN_NETWSSend s
switch (send) { switch (send) {
default: DN_InvalidCodePath; break; default: DN_InvalidCodePath; break;
case DN_NETWSSend_Text: { case DN_NETWSSend_Text: {
DN_U64 pos = DN_ArenaPos(&request_ptr->arena); DN_U64 pos = DN_MemListPos(request_ptr->start_response_arena.mem);
DN_Str8 data_null_terminated = DN_Str8FromStr8Arena(&request_ptr->arena, data); 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); 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; } break;
case DN_NETWSSend_Binary: { case DN_NETWSSend_Binary: {
@@ -320,7 +317,7 @@ static DN_NETResponse DN_NET_EmcHandleFinishedRequest_(DN_NETCore *net, DN_NETEm
bool end_request = true; bool end_request = true;
bool dequeue_request = true; bool dequeue_request = true;
if (request->type == DN_NETRequestType_HTTP) { if (request->type == DN_NETRequestType_HTTP) {
result.body = DN_Str8FromStr8Arena(arena, result.body); result.body = DN_Str8FromStr8Arena(result.body, arena);
} else { } else {
// NOTE: Get emscripten contexts // NOTE: Get emscripten contexts
DN_NETEmcWSEvent *emc_event = emc_request->first_event; 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 // NOTE: Build the result
result.state = emc_event->state; result.state = emc_event->state;
result.request = handle; result.request = handle;
result.body = DN_Str8FromStr8Arena(arena, emc_event->payload); result.body = DN_Str8FromStr8Arena(emc_event->payload, arena);
// NOTE: Advance the event list // 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 // NOTE: Deallocate the memory used in the request and reset the string builder (as all
// payload(s) have been read from the request). // payload(s) have been read from the request).
if (end_request) if (!end_request)
DN_ArenaPopTo(&request->arena, 0); DN_ArenaTempEnd(&request->start_response_arena, DN_ArenaReset_Yes);
else
DN_ArenaPopTo(&request->arena, request->start_response_arena_pos);
} }
if (end_request) { if (end_request) {
+5 -5
View File
@@ -449,11 +449,11 @@ static DN_UTCore DN_TST_BaseArena()
// NOTE: Allocate 128 kilobytes, fill it with garbage, then reset the arena // NOTE: Allocate 128 kilobytes, fill it with garbage, then reset the arena
uintptr_t first_ptr_address = 0; uintptr_t first_ptr_address = 0;
{ {
DN_Arena temp_mem = DN_ArenaTempBeginFromArena(&arena); DN_U64 mem_p = DN_MemListPos(arena.mem);
void *ptr = DN_ArenaAlloc(&arena, alloc_size, alignment, DN_ZMem_Yes); void *ptr = DN_ArenaAlloc(&arena, alloc_size, alignment, DN_ZMem_Yes);
first_ptr_address = DN_Cast(uintptr_t) ptr; first_ptr_address = DN_Cast(uintptr_t) ptr;
DN_Memset(ptr, 'z', alloc_size); DN_Memset(ptr, 'z', alloc_size);
DN_ArenaTempEnd(&temp_mem, DN_ArenaReset_Yes); DN_MemListPopTo(arena.mem, mem_p);
} }
// NOTE: Reallocate 128 kilobytes // 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); char *ptr_1mb = DN_Cast(char *) DN_ArenaAlloc(&arena, DN_Megabytes(1), 1 /*align*/, DN_ZMem_Yes);
DN_UT_Assert(&result, ptr_1mb); 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_UT_Assert(&result, ptr_4mb);
DN_MemBlock const *block_4mb_begin = arena.mem->curr; 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_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_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_Assert(&result, arena.mem->curr->prev == nullptr);
DN_UT_AssertF(&result, DN_UT_AssertF(&result,
arena.mem->curr->reserve >= DN_Megabytes(1), arena.mem->curr->reserve >= DN_Megabytes(1),
+32 -36
View File
@@ -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_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_OSDiskSpace result = {};
DN_Str8 path_z_terminated = DN_Str8FromStr8Arena(tmem.arena, path); DN_Str8 path_z_terminated = DN_Str8FromStr8Arena(path, &scratch.arena);
struct statvfs info = {}; struct statvfs info = {};
if (statvfs(path_z_terminated.data, &info) != 0) { if (statvfs(path_z_terminated.data, &info) == 0) {
DN_TCScratchEnd(&tmem);
return result;
}
result.success = true; result.success = true;
result.avail = info.f_bavail * info.f_frsize; result.avail = info.f_bavail * info.f_frsize;
result.size = info.f_blocks * info.f_frsize; result.size = info.f_blocks * info.f_frsize;
DN_TCScratchEnd(&tmem); }
DN_TCScratchEnd(&scratch);
return result; return result;
} }
@@ -251,9 +247,9 @@ DN_API DN_Str8 DN_OS_EXEPath(DN_Arena *arena)
if (!arena) if (!arena)
return result; return result;
DN_U64 mem_p = DN_MemListPos(arena->mem);
int required_size_wo_null_terminator = 0; int required_size_wo_null_terminator = 0;
for (int try_size = 128;; try_size *= 2) { 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); char *try_buf = DN_ArenaNewArray(arena, char, try_size, DN_ZMem_No);
int bytes_written = readlink("/proc/self/exe", try_buf, try_size); int bytes_written = readlink("/proc/self/exe", try_buf, try_size);
if (bytes_written == -1) { if (bytes_written == -1) {
@@ -280,11 +276,11 @@ DN_API DN_Str8 DN_OS_EXEPath(DN_Arena *arena)
break; break;
} }
} }
DN_MemListPopTo(arena->mem, mem_p);
if (required_size_wo_null_terminator) { if (required_size_wo_null_terminator) {
DN_ArenaTempMem temp_mem = DN_ArenaTempMemBegin(arena); mem_p = DN_MemListPos(arena->mem);
char *exe_path = char *exe_path = DN_ArenaNewArray(arena, char, required_size_wo_null_terminator + 1, DN_ZMem_No);
DN_ArenaNewArray(arena, char, required_size_wo_null_terminator + 1, DN_ZMem_No);
exe_path[required_size_wo_null_terminator] = 0; exe_path[required_size_wo_null_terminator] = 0;
int bytes_written = readlink("/proc/self/exe", exe_path, required_size_wo_null_terminator); 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 // Note that if read-link fails again can be because there's
// a potential race condition here, our exe or directory could have // a potential race condition here, our exe or directory could have
// been deleted since the last call, so we need to be careful. // been deleted since the last call, so we need to be careful.
DN_ArenaTempMemEnd(temp_mem); DN_MemListPopTo(arena->mem, mem_p);
} else { } else {
result = DN_Str8FromPtr(exe_path, required_size_wo_null_terminator); result = DN_Str8FromPtr(exe_path, required_size_wo_null_terminator);
} }
@@ -639,7 +635,7 @@ DN_API bool DN_OS_PathMakeDir(DN_Str8 path)
DN_USize path_indexes_size = 0; DN_USize path_indexes_size = 0;
uint16_t path_indexes[64] = {}; 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--) { for (DN_USize index = copy.size - 1; index < copy.size; index--) {
bool first_char = index == (copy.size - 1); bool first_char = index == (copy.size - 1);
char ch = copy.data[index]; char ch = copy.data[index];
@@ -674,7 +670,7 @@ DN_API bool DN_OS_PathMakeDir(DN_Str8 path)
} }
for (DN_USize index = path_indexes_size - 1; result && index < path_indexes_size; index--) { for (DN_USize index = path_indexes_size - 1; result && index < path_indexes_size; index--) {
uint16_t path_index = path_indexes[index]; DN_U16 path_index = path_indexes[index];
char temp = copy.data[path_index]; char temp = copy.data[path_index];
if (index != 0) if (index != 0)
@@ -800,7 +796,7 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle,
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1); DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
if (arena && handle.stdout_read) { if (arena && handle.stdout_read) {
char buffer[4096]; char buffer[4096];
DN_Str8Builder builder = DN_Str8BuilderFromArena(scratch.arena); DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
for (;;) { for (;;) {
ssize_t bytes_read = ssize_t bytes_read =
read(stdout_pipe[DN_OSPipeType__Read], buffer, sizeof(buffer)); 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) { if (arena && handle.stderr_read) {
char buffer[4096]; char buffer[4096];
DN_Str8Builder builder = DN_Str8BuilderFromArena(scratch.arena); DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
for (;;) { for (;;) {
ssize_t bytes_read = ssize_t bytes_read =
read(stderr_pipe[DN_OSPipeType__Read], buffer, sizeof(buffer)); 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_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_DEFER { DN_TCScratchEnd(&scratch); }; 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 stdout_pipe[DN_OSPipeType__Count] = {};
int stderr_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 // NOTE: Convert the command into something suitable for execvp
char **argv = 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) { if (!argv) {
result.exit_code = -1; result.exit_code = -1;
DN_ErrSinkAppendF( 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)) { for (DN_ForIndexU(arg_index, cmd_line.count)) {
DN_Str8 arg = cmd_line.data[arg_index]; 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 // 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) { if (args->working_dir.size) {
prev_working_dir = get_current_dir_name(); 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) { if (chdir(working_dir.data) == -1) {
result.os_error_code = errno; result.os_error_code = errno;
DN_ErrSinkAppendF( DN_ErrSinkAppendF(
@@ -1374,11 +1370,11 @@ DN_API void DN_OS_PosixThreadSetName(DN_Str8 name)
#if defined(DN_PLATFORM_EMSCRIPTEN) #if defined(DN_PLATFORM_EMSCRIPTEN)
(void)name; (void)name;
#else #else
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0); DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str8 copy = DN_Str8FromStr8Arena(tmem.arena, name); DN_Str8 copy = DN_Str8FromStr8Arena(name, &scratch.arena);
pthread_t thread = pthread_self(); pthread_t thread = pthread_self();
pthread_setname_np(thread, (char *)copy.data); pthread_setname_np(thread, (char *)copy.data);
DN_TCScratchEnd(&tmem); DN_TCScratchEnd(&scratch);
#endif #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); DN_OSFile file = DN_OS_FileOpen(DN_Str8Lit("/proc/self/status"), DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_Read, nullptr);
if (!file.error) { if (!file.error) {
DN_TCScratch tmem = DN_TCScratchBegin(nullptr, 0); DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
char buf[256]; char buf[256];
DN_Str8Builder builder = DN_Str8BuilderFromArena(tmem.arena); DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
for (;;) { for (;;) {
DN_OSFileRead read = DN_OS_FileRead(&file, buf, sizeof(buf), nullptr); DN_OSFileRead read = DN_OS_FileRead(&file, buf, sizeof(buf), nullptr);
if (!read.success || read.bytes_read == 0) 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 PID = DN_Str8Lit("Pid:");
DN_Str8 const VM_PEAK = DN_Str8Lit("VmPeak:"); DN_Str8 const VM_PEAK = DN_Str8Lit("VmPeak:");
DN_Str8 const VM_SIZE = DN_Str8Lit("VmSize:"); DN_Str8 const VM_SIZE = DN_Str8Lit("VmSize:");
DN_Str8 status_buf = DN_Str8BuilderBuild(&builder, tmem.arena); DN_Str8 status_buf = DN_Str8BuilderBuild(&builder, &scratch.arena);
DN_Str8SplitResult lines = DN_Str8SplitArena(tmem.arena, status_buf, DN_Str8Lit("\n"), DN_Str8SplitIncludeEmptyStrings_No); 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)) { for (DN_ForItSize(line_it, DN_Str8, lines.data, lines.count)) {
DN_Str8 line = DN_Str8TrimWhitespaceAround(*line_it.data); 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_Assert(to_u64.success);
} }
} }
DN_TCScratchEnd(&tmem); DN_TCScratchEnd(&scratch);
} }
DN_OS_FileClose(&file); DN_OS_FileClose(&file);
return result; return result;
@@ -1499,7 +1495,7 @@ static void DN_OS_HttpRequestEMFetchOnSuccessCallback(emscripten_fetch_t *fetch)
return; return;
response->http_status = DN_Cast(DN_U32) fetch->status; 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) if (response->body.data)
DN_Memcpy(response->body.data, fetch->data, fetch->numBytes); DN_Memcpy(response->body.data, fetch->data, fetch->numBytes);
@@ -1514,7 +1510,7 @@ static void DN_OS_HttpRequestEMFetchOnErrorCallback(emscripten_fetch_t *fetch)
return; return;
response->http_status = DN_Cast(DN_U32) fetch->status; 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) if (response->body.size)
DN_Memcpy(response->body.data, fetch->data, fetch->numBytes); DN_Memcpy(response->body.data, fetch->data, fetch->numBytes);
@@ -1536,13 +1532,13 @@ DN_API void DN_OS_HttpRequestAsync(DN_OSHttpResponse *response,
return; return;
response->arena = arena; 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_TCScratch scratch_ = DN_TCScratchBegin(&arena, 1);
DN_DEFER { DN_TCScratchEnd(&scratch_); }; DN_DEFER { DN_TCScratchEnd(&scratch_); };
if (!scratch) if (!scratch)
scratch = scratch_.arena; scratch = &scratch_.arena;
#if defined(DN_PLATFORM_EMSCRIPTEN) #if defined(DN_PLATFORM_EMSCRIPTEN)
emscripten_fetch_attr_t fetch_attribs = {}; 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) #endif // #elif defined(DN_OS_WIN32)
DN_ArenaDeinit(&response->tmp_arena); DN_MemListDeinit(response->tmp_arena.mem);
DN_OS_SemaphoreDeinit(&response->on_complete_semaphore); DN_OS_SemaphoreDeinit(&response->on_complete_semaphore);
*response = {}; *response = {};
} }
+1 -1
View File
@@ -1,4 +1,4 @@
#if (_CLANGD) #if defined(_CLANGD)
#define DN_H_WITH_OS 1 #define DN_H_WITH_OS 1
#include "dn.h" #include "dn.h"
#endif #endif
+1 -1
View File
@@ -39,7 +39,7 @@ pushd %build_dir%
where /q emcc && ( where /q emcc && (
echo [BUILD] Emscripten emcc detected, compiling ... 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 && ( where /q cl && (
+6 -11
View File
@@ -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); DN_ErrSinkEndExitIfErrorF(err, -1, "Failed to load file from '%S' for appending", cpp_path);
bool inside_clangd_preprocessor_block = false; bool inside_clangd_preprocessor_block = false;
for (DN_Str8 inc_walker = buffer;;) { for (DN_Str8 walker = buffer; walker.size;) {
DN_Str8BSplitResult split = DN_Str8BSplit(inc_walker, DN_Str8Lit("\n"));
if (split.lhs.size == 0)
break;
inc_walker = split.rhs;
// NOTE: Trim the whitespace, mainly for windows, the file we read will have \r\n whereas we just want to emit \n // NOTE: Trim the whitespace, mainly for windows, the file we read will have \r\n whereas we just want to emit \n
DN_Str8BSplitResult split = DN_Str8BSplit(walker, DN_Str8Lit("\n"));
DN_Str8 line = DN_Str8TrimTailWhitespace(split.lhs); DN_Str8 line = DN_Str8TrimTailWhitespace(split.lhs);
walker = split.rhs;
// NOTE: Detect if we're inside a clangd preprocessor block // 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) // 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_Str8 const REL_FILE_PATHS[] = {
DN_Str8Lit("dn"), DN_Str8Lit("dn"),
DN_Str8Lit("Extra/dn_async"),
DN_Str8Lit("Extra/dn_bin_pack"), DN_Str8Lit("Extra/dn_bin_pack"),
DN_Str8Lit("Extra/dn_csv"), DN_Str8Lit("Extra/dn_csv"),
DN_Str8Lit("Extra/dn_helpers"),
}; };
for (DN_ForIndexU(type, FileType_Count)) { for (DN_ForIndexU(type, FileType_Count)) {
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0); DN_TCScratch scratch = DN_TCScratchBegin(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(extra_it, DN_Str8 const, REL_FILE_PATHS)) { for (DN_ForItCArray(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); DN_Str8 path = DN_OS_PathF(&scratch.arena, "%S/%S.%S", dn_root_dir, *it.data, suffix);
AppendCppFileLineByLine(&builder, extra_path); AppendCppFileLineByLine(&builder, path);
} }
DN_Date date = DN_OS_DateLocalTimeNow(); DN_Date date = DN_OS_DateLocalTimeNow();