Get latest changes from Primitive Indexer"
This commit is contained in:
+278
-111
@@ -1,4 +1,4 @@
|
||||
// Generated by the DN single header generator 2026-07-05 23:26:32
|
||||
// Generated by the DN single header generator 2026-07-07 23:09:14
|
||||
|
||||
// DN: Single header generator commented out => #if defined(_CLANGD)
|
||||
// #define DN_WITH_TESTS 1
|
||||
@@ -548,24 +548,24 @@ DN_API DN_CPUReport DN_CPUGetReport()
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void DN_TicketMutex_Begin(DN_TicketMutex *mutex)
|
||||
DN_API void DN_TicketMutexBegin(DN_TicketMutex *mutex)
|
||||
{
|
||||
DN_UInt ticket = DN_AtomicAddU32(&mutex->ticket, 1);
|
||||
DN_TicketMutex_BeginTicket(mutex, ticket);
|
||||
DN_TicketMutexBeginTicket(mutex, ticket);
|
||||
}
|
||||
|
||||
DN_API void DN_TicketMutex_End(DN_TicketMutex *mutex)
|
||||
DN_API void DN_TicketMutexEnd(DN_TicketMutex *mutex)
|
||||
{
|
||||
DN_AtomicAddU32(&mutex->serving, 1);
|
||||
}
|
||||
|
||||
DN_API DN_UInt DN_TicketMutex_MakeTicket(DN_TicketMutex *mutex)
|
||||
DN_API DN_UInt DN_TicketMutexMakeTicket(DN_TicketMutex *mutex)
|
||||
{
|
||||
DN_UInt result = DN_AtomicAddU32(&mutex->ticket, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void DN_TicketMutex_BeginTicket(DN_TicketMutex const *mutex, DN_UInt ticket)
|
||||
DN_API void DN_TicketMutexBeginTicket(DN_TicketMutex const *mutex, DN_UInt ticket)
|
||||
{
|
||||
DN_AssertF(mutex->serving <= ticket,
|
||||
"Mutex skipped ticket? Was ticket generated by the correct mutex via MakeTicket? ticket = %u, "
|
||||
@@ -578,7 +578,7 @@ DN_API void DN_TicketMutex_BeginTicket(DN_TicketMutex const *mutex, DN_UInt tick
|
||||
}
|
||||
}
|
||||
|
||||
DN_API bool DN_TicketMutex_CanLock(DN_TicketMutex const *mutex, DN_UInt ticket)
|
||||
DN_API bool DN_TicketMutexCanLock(DN_TicketMutex const *mutex, DN_UInt ticket)
|
||||
{
|
||||
bool result = (ticket == mutex->serving);
|
||||
return result;
|
||||
@@ -1768,6 +1768,12 @@ DN_API void DN_ArenaDeinit(DN_Arena *arena)
|
||||
DN_MemListDeinit(arena->mem);
|
||||
}
|
||||
|
||||
DN_API bool DN_ArenaOwnsPtr(DN_Arena const *arena, void *ptr)
|
||||
{
|
||||
bool result = DN_MemListOwnsPtr(arena->mem, ptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Pool DN_PoolFromArena(DN_Arena *arena, DN_U8 align)
|
||||
{
|
||||
DN_Pool result = {};
|
||||
@@ -5058,7 +5064,6 @@ DN_API DN_U8x16 DN_U8x16FromPtrHex32(char const *hex, DN_USize hex_count)
|
||||
{
|
||||
DN_U8x16 result = {};
|
||||
DN_Str8 hex_trimmed = DN_Str8TrimHexPrefix(DN_Str8FromPtr(hex, hex_count));
|
||||
DN_Assert(hex_trimmed.count / 2 == sizeof result.data);
|
||||
DN_USize bytes_written = DN_PtrBytesFromStr8Hex(hex_trimmed, result.data, sizeof result.data);
|
||||
DN_Assert(bytes_written == sizeof result.data);
|
||||
return result;
|
||||
@@ -5068,7 +5073,6 @@ DN_API DN_U8x32 DN_U8x32FromPtrHex64(char const *hex, DN_USize hex_count)
|
||||
{
|
||||
DN_U8x32 result = {};
|
||||
DN_Str8 hex_trimmed = DN_Str8TrimHexPrefix(DN_Str8FromPtr(hex, hex_count));
|
||||
DN_Assert(hex_trimmed.count / 2 == sizeof result.data);
|
||||
DN_USize bytes_written = DN_PtrBytesFromStr8Hex(hex_trimmed, result.data, sizeof result.data);
|
||||
DN_Assert(bytes_written == sizeof result.data);
|
||||
return result;
|
||||
@@ -8094,6 +8098,7 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2(DN_V2F32 origin_a, DN_V2F32 dir_a,
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef struct DN_ArrayFindEqMemcmpContext_ DN_ArrayFindEqMemcmpContext_;
|
||||
struct DN_ArrayFindEqMemcmpContext_
|
||||
{
|
||||
DN_USize elem_size;
|
||||
@@ -9629,6 +9634,7 @@ DN_API void DN_TestVerifyBytesF(DN_TestCore *test, DN_CallSite call_site, DN_Str
|
||||
#if defined(DN_PLATFORM_WIN32) && defined(DN_COMPILER_MSVC)
|
||||
// NOTE: Taken from MSDN __cpuid example implementation
|
||||
// https://learn.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex?view=msvc-170
|
||||
typedef struct DN_RefImplCPUReport DN_RefImplCPUReport;
|
||||
struct DN_RefImplCPUReport {
|
||||
unsigned int nIds_ = 0;
|
||||
unsigned int nExIds_ = 0;
|
||||
@@ -9791,22 +9797,22 @@ DN_API DN_TestCore DN_TestSuite(DN_Arena *arena_)
|
||||
{
|
||||
for (DN_TestScopeF(&result, "[TicketMutex] Start and stop")) {
|
||||
DN_TicketMutex mutex = {};
|
||||
DN_TicketMutex_Begin(&mutex);
|
||||
DN_TicketMutex_End(&mutex);
|
||||
DN_TicketMutexBegin(&mutex);
|
||||
DN_TicketMutexEnd(&mutex);
|
||||
DN_TestVerifyUSizeEq(&result, mutex.ticket, mutex.serving);
|
||||
}
|
||||
|
||||
for (DN_TestScopeF(&result, "[TicketMutex] Start and stop w/ advanced API")) {
|
||||
DN_TicketMutex mutex = {};
|
||||
unsigned int ticket_a = DN_TicketMutex_MakeTicket(&mutex);
|
||||
unsigned int ticket_b = DN_TicketMutex_MakeTicket(&mutex);
|
||||
DN_TestVerifyExpr(&result, DN_Cast(bool) DN_TicketMutex_CanLock(&mutex, ticket_b) == false);
|
||||
DN_TestVerifyExpr(&result, DN_Cast(bool) DN_TicketMutex_CanLock(&mutex, ticket_a) == true);
|
||||
DN_UInt ticket_a = DN_TicketMutexMakeTicket(&mutex);
|
||||
DN_UInt ticket_b = DN_TicketMutexMakeTicket(&mutex);
|
||||
DN_TestVerifyExpr(&result, DN_Cast(bool) DN_TicketMutexCanLock(&mutex, ticket_b) == false);
|
||||
DN_TestVerifyExpr(&result, DN_Cast(bool) DN_TicketMutexCanLock(&mutex, ticket_a) == true);
|
||||
|
||||
DN_TicketMutex_BeginTicket(&mutex, ticket_a);
|
||||
DN_TicketMutex_End(&mutex);
|
||||
DN_TicketMutex_BeginTicket(&mutex, ticket_b);
|
||||
DN_TicketMutex_End(&mutex);
|
||||
DN_TicketMutexBeginTicket(&mutex, ticket_a);
|
||||
DN_TicketMutexEnd(&mutex);
|
||||
DN_TicketMutexBeginTicket(&mutex, ticket_b);
|
||||
DN_TicketMutexEnd(&mutex);
|
||||
|
||||
DN_TestVerifyUSizeEq(&result, mutex.ticket, mutex.serving);
|
||||
DN_TestVerifyUSizeEq(&result, mutex.ticket, ticket_b + 1);
|
||||
@@ -11289,7 +11295,7 @@ DN_API void DN_LeakTrackAlloc_(DN_LeakTracker *leak, void *ptr, DN_USize size, b
|
||||
if (!ptr)
|
||||
return;
|
||||
|
||||
DN_TicketMutex_Begin(&leak->alloc_table_mutex);
|
||||
DN_TicketMutexBegin(&leak->alloc_table_mutex);
|
||||
|
||||
DN_Str8 stack_trace = DN_Str8FromStackTraceNowHeap(128, 3 /*skip*/);
|
||||
DN_HTable* alloc_table = &leak->alloc_table;
|
||||
@@ -11335,7 +11341,7 @@ DN_API void DN_LeakTrackAlloc_(DN_LeakTracker *leak, void *ptr, DN_USize size, b
|
||||
alloc->stack_trace = stack_trace;
|
||||
alloc->flags |= leak_permitted ? DN_LeakAllocFlag_LeakPermitted : 0;
|
||||
leak->alloc_table_bytes_allocated_for_stack_traces += alloc->stack_trace.count;
|
||||
DN_TicketMutex_End(&leak->alloc_table_mutex);
|
||||
DN_TicketMutexEnd(&leak->alloc_table_mutex);
|
||||
}
|
||||
|
||||
DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr)
|
||||
@@ -11343,7 +11349,7 @@ DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr)
|
||||
if (!ptr)
|
||||
return;
|
||||
|
||||
DN_TicketMutex_Begin(&leak->alloc_table_mutex);
|
||||
DN_TicketMutexBegin(&leak->alloc_table_mutex);
|
||||
|
||||
DN_Str8 stack_trace = DN_Str8FromStackTraceNowHeap(128, 3 /*skip*/);
|
||||
DN_HTable* alloc_table = &leak->alloc_table;
|
||||
@@ -11384,7 +11390,7 @@ DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr)
|
||||
alloc->flags |= DN_LeakAllocFlag_Freed;
|
||||
alloc->freed_stack_trace = stack_trace;
|
||||
leak->alloc_table_bytes_allocated_for_stack_traces += alloc->freed_stack_trace.count;
|
||||
DN_TicketMutex_End(&leak->alloc_table_mutex);
|
||||
DN_TicketMutexEnd(&leak->alloc_table_mutex);
|
||||
}
|
||||
|
||||
DN_API void DN_LeakDump_(DN_LeakTracker *leak)
|
||||
@@ -11446,52 +11452,150 @@ DN_API DN_Str8 DN_OS_Str8FromStr8BuilderHeap(DN_Str8Builder const *builder)
|
||||
|
||||
DN_API void DN_OS_LogPrint(DN_LogTypeParam type, void *user_data, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||
{
|
||||
DN_Assert(user_data);
|
||||
DN_OSCore *os = DN_Cast(DN_OSCore *)user_data;
|
||||
DN_OSLogger *logger = &os->logger;
|
||||
DN_OS_LoggerFV(logger, type, call_site, flags, fmt, args);
|
||||
}
|
||||
|
||||
// NOTE: Open log file for appending if requested
|
||||
DN_TicketMutex_Begin(&os->log_file_mutex);
|
||||
if (os->log_to_file && !os->log_file.handle && !os->log_file.error) {
|
||||
DN_API DN_Str8 DN_OS_LoggerGetRotateFilePath(DN_Str8 base_file_path, DN_Arena *arena, DN_USize rotate_index)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (rotate_index == 0)
|
||||
result = DN_OS_PathFmtArena(arena, "%.*s", DN_Str8PrintFmt(base_file_path));
|
||||
else
|
||||
result = DN_OS_PathFmtArena(arena, "%.*s.%zu", DN_Str8PrintFmt(base_file_path), rotate_index);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void DN_OS_LoggerSetFilePathNoMutex_(DN_OSLogger *logger, DN_Pool *pool, DN_Str8 file_path)
|
||||
{
|
||||
if (logger->file_path.data) {
|
||||
DN_AssertF(DN_MemListOwnsPtr(pool->arena->mem, logger->file_path.data),
|
||||
"If there's a pre-existing file path set in the logger, it must be deallocated by "
|
||||
" the caller and cleared. If it has been previously allocated with the exact same "
|
||||
" pool was allocated with the same pool then we will deallocate it for you.");
|
||||
DN_PoolDealloc(pool, logger->file_path.data);
|
||||
logger->file_path = {};
|
||||
}
|
||||
DN_OS_FileClose(&logger->file);
|
||||
logger->file_path = DN_OS_PathFmtPool(pool, "%.*s", DN_Str8PrintFmt(file_path));
|
||||
|
||||
// NOTE: Clear the sticky file error flag if it was set
|
||||
logger->flags &= ~DN_OSLoggerFlags_FileError;
|
||||
}
|
||||
|
||||
DN_API void DN_OS_LoggerSetFilePath(DN_OSLogger *logger, DN_Pool *pool, DN_Str8 file_path)
|
||||
{
|
||||
DN_TicketMutexBegin(&logger->file_mutex);
|
||||
DN_OS_LoggerSetFilePathNoMutex_(logger, pool, file_path);
|
||||
DN_TicketMutexEnd(&logger->file_mutex);
|
||||
}
|
||||
|
||||
static void DN_OS_DoLogFileSetupAndRotation_(DN_OSLogger *logger)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||
DN_Str8 error = {};
|
||||
DN_TicketMutexBegin(&logger->file_mutex);
|
||||
if (logger->flags & DN_OSLoggerFlags_File) {
|
||||
|
||||
// NOTE: Set a default file path to log to if it's not been set yet
|
||||
if (logger->file_path.count == 0) {
|
||||
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));
|
||||
os->log_file = DN_OS_FileOpen(log_path, DN_OSFileOpen_CreateAlways, DN_OSFileAccess_AppendOnly, nullptr);
|
||||
DN_Str8 default_file_path = DN_OS_PathFmtArena(&scratch.arena, "%.*s/dn.log", DN_Str8PrintFmt(exe_dir));
|
||||
DN_OS_LoggerSetFilePathNoMutex_(logger, DN_TCMainPool(), default_file_path);
|
||||
}
|
||||
|
||||
// NOTE Rotate the log file if the criteria is met
|
||||
if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_FileError) && logger->rotate_every_n_bytes && logger->rotate_count) {
|
||||
DN_Assert(logger->file_path.count);
|
||||
DN_Assert(logger->rotate_every_n_bytes > 0);
|
||||
|
||||
DN_OSPathInfo file_info = DN_OS_PathInfo(logger->file_path);
|
||||
bool needs_rotate = file_info.size >= logger->rotate_every_n_bytes;
|
||||
if (needs_rotate) {
|
||||
DN_OS_FileClose(&logger->file);
|
||||
// NOTE: Loop through all the rotated log files from [rotate_count-1..1]. The rotated log
|
||||
// file at `rotate_count-1` gets deleted and `rotate_count-2` gets moved into
|
||||
// `rotate_count-1` and so forth
|
||||
for (DN_USize offset = 0; offset < (logger->rotate_count - 1); offset++) {
|
||||
DN_USize const file_index = logger->rotate_count - (offset + 1);
|
||||
DN_Str8 file_path = DN_OS_LoggerGetRotateFilePath(logger->file_path, &scratch.arena, file_index);
|
||||
DN_Str8 prev_file_path = DN_OS_LoggerGetRotateFilePath(logger->file_path, &scratch.arena, file_index - 1);
|
||||
DN_OS_FileMove(prev_file_path, file_path, true, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: After rotating, check the file size of the log file we will write to again. If the
|
||||
// file size is still greater than the rotate size, then there was an error when we
|
||||
// attempted to rotate the logs. Set the sticky file flag error to disable to logger and
|
||||
// inform the user.
|
||||
if (needs_rotate) {
|
||||
DN_OSPathInfo recheck_file_info = DN_OS_PathInfo(logger->file_path);
|
||||
if (recheck_file_info.size >= logger->rotate_every_n_bytes) {
|
||||
logger->flags |= DN_OSLoggerFlags_FileError;
|
||||
error = DN_Str8FromFmtArena(&scratch.arena, "Rotating of log files failed at (%.*s). Logging to disk is disabled", DN_Str8PrintFmt(logger->file_path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Open the file requested by the logger if it hasn't been opened yet
|
||||
if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_FileError)) {
|
||||
if (!logger->file.handle && !logger->file.error) {
|
||||
DN_OSPathInfo file_path_info = DN_OS_PathInfo(logger->file_path);
|
||||
if (file_path_info.exists && file_path_info.type != DN_OSPathInfoType_File) {
|
||||
logger->flags |= DN_OSLoggerFlags_FileError;
|
||||
error = DN_Str8FromFmtArena(&scratch.arena, "File path to log to (%.*s) exists but is not a writable file. Logging to disk is disabled.", DN_Str8PrintFmt(logger->file_path));
|
||||
}
|
||||
|
||||
if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_FileError))
|
||||
logger->file = DN_OS_FileOpen(logger->file_path, DN_OSFileOpen_OpenAlways, DN_OSFileAccess_AppendOnly, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Set the sticky error flag on the file if opening failed. The sticky flag ensures we
|
||||
// only notify the user once of a file open failure per unique base file path
|
||||
if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_FileError)) {
|
||||
if (logger->file.error) {
|
||||
logger->flags |= DN_OSLoggerFlags_FileError;
|
||||
error = DN_Str8FromFmtArena(&scratch.arena, "Failed to open file (%.*s) for logging. Logging to disk is disabled", DN_Str8PrintFmt(logger->file_path));
|
||||
}
|
||||
}
|
||||
}
|
||||
DN_TicketMutexEnd(&logger->file_mutex);
|
||||
|
||||
// NOTE: Error is logged outside of the mutex since logging will recurse back into the OS logger
|
||||
if (error.count)
|
||||
DN_LogWarningF("%.*s", DN_Str8PrintFmt(error));
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
DN_TicketMutex_End(&os->log_file_mutex);
|
||||
|
||||
DN_API void DN_OS_LoggerFV(DN_OSLogger *logger, DN_LogTypeParam type, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||
{
|
||||
DN_OS_DoLogFileSetupAndRotation_(logger);
|
||||
bool print_prefix = DN_BitIsNotSet(flags, DN_LogFlags_NoPrefix);
|
||||
char prefix_buffer[128] = {};
|
||||
DN_LogPrefixSize prefix_size = {};
|
||||
char prefix_colour_buffer[128] = {};
|
||||
DN_LogPrefixSize prefix_colour_size = {};
|
||||
if (print_prefix) {
|
||||
DN_LogStyle style = {};
|
||||
if (!os->log_no_colour) {
|
||||
style.colour = true;
|
||||
style.bold = DN_LogBold_Yes;
|
||||
// NOTE: Generate 2 variants of the style (colour and colour-less) for printing the prefix of
|
||||
// the log line
|
||||
DN_LogStyle style_colour = {};
|
||||
style_colour.bold = DN_LogBold_Yes;
|
||||
style_colour.colour = true;
|
||||
if (type.is_u32_enum) {
|
||||
switch (type.u32) {
|
||||
case DN_LogType_Debug: {
|
||||
case DN_LogType_Debug: style_colour.colour = false; style_colour.bold = DN_LogBold_No; break;
|
||||
case DN_LogType_Info: style_colour.g = 0x87; style_colour.b = 0xff; break;
|
||||
case DN_LogType_Warning: style_colour.r = 0xff; style_colour.g = 0xff; break;
|
||||
case DN_LogType_Error: style_colour.r = 0xff; break;
|
||||
}
|
||||
}
|
||||
|
||||
DN_LogStyle style = style_colour;
|
||||
style.colour = false;
|
||||
style.bold = DN_LogBold_No;
|
||||
} break;
|
||||
|
||||
case DN_LogType_Info: {
|
||||
style.g = 0x87;
|
||||
style.b = 0xff;
|
||||
} break;
|
||||
|
||||
case DN_LogType_Warning: {
|
||||
style.r = 0xff;
|
||||
style.g = 0xff;
|
||||
} break;
|
||||
|
||||
case DN_LogType_Error: {
|
||||
style.r = 0xff;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Build the log prefix
|
||||
DN_Date os_date = DN_OS_DateLocalTimeNow();
|
||||
DN_LogDate log_date = {};
|
||||
log_date.year = os_date.year;
|
||||
@@ -11500,35 +11604,50 @@ DN_API void DN_OS_LogPrint(DN_LogTypeParam type, void *user_data, DN_CallSite ca
|
||||
log_date.hour = os_date.hour;
|
||||
log_date.minute = os_date.minutes;
|
||||
log_date.second = os_date.seconds;
|
||||
prefix_size = DN_LogMakePrefix(style, type, call_site, log_date, prefix_buffer, sizeof(prefix_buffer));
|
||||
prefix_size = DN_LogMakePrefix(style, type, call_site, log_date, prefix_buffer, DN_ArrayCountU(prefix_buffer));
|
||||
prefix_colour_size = DN_LogMakePrefix(style_colour, type, call_site, log_date, prefix_colour_buffer, DN_ArrayCountU(prefix_colour_buffer));
|
||||
}
|
||||
|
||||
// NOTE: Log to disk. Note that a file handle that error-ed is a no-op in these functions so no
|
||||
// extra branching is needed to handle that.
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
DN_TicketMutex_Begin(&os->log_file_mutex);
|
||||
DN_TicketMutexBegin(&logger->file_mutex);
|
||||
{
|
||||
if (print_prefix) {
|
||||
DN_OS_FileWrite(&os->log_file, DN_Str8FromPtr(prefix_buffer, prefix_size.count), nullptr);
|
||||
DN_OS_FileWriteF(&os->log_file, nullptr, "%*s ", DN_Cast(int) prefix_size.padding, "");
|
||||
DN_OS_FileWrite(&logger->file, DN_Str8FromPtr(prefix_buffer, prefix_size.count), nullptr);
|
||||
DN_OS_FileWriteF(&logger->file, nullptr, "%*s ", DN_Cast(int) prefix_size.padding, "");
|
||||
}
|
||||
DN_OS_FileWriteFV(&os->log_file, nullptr, fmt, args_copy);
|
||||
DN_OS_FileWriteFV(&logger->file, nullptr, fmt, args_copy);
|
||||
if (!DN_BitIsSet(flags, DN_LogFlags_NoNewLine))
|
||||
DN_OS_FileWrite(&os->log_file, DN_Str8Lit("\n"), nullptr);
|
||||
DN_OS_FileWrite(&logger->file, DN_Str8Lit("\n"), nullptr);
|
||||
}
|
||||
DN_TicketMutex_End(&os->log_file_mutex);
|
||||
DN_TicketMutexEnd(&logger->file_mutex);
|
||||
va_end(args_copy);
|
||||
|
||||
DN_TicketMutex_Begin(&os->log_mutex);
|
||||
{
|
||||
if (print_prefix)
|
||||
DN_TicketMutexBegin(&logger->mutex);
|
||||
if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_NoOutput)) {
|
||||
if (print_prefix) {
|
||||
if (DN_BitIsSet(logger->flags, DN_OSLoggerFlags_NoColour))
|
||||
DN_OS_PrintF(DN_OSPrintDest_Err, "%.*s%*s ", DN_Cast(int) prefix_size.count, prefix_buffer, DN_Cast(int) prefix_size.padding, "");
|
||||
else
|
||||
DN_OS_PrintF(DN_OSPrintDest_Err, "%.*s%*s ", DN_Cast(int) prefix_colour_size.count, prefix_colour_buffer, DN_Cast(int) prefix_colour_size.padding, "");
|
||||
}
|
||||
|
||||
if (DN_BitIsSet(flags, DN_LogFlags_NoNewLine))
|
||||
DN_OS_PrintFV(DN_OSPrintDest_Err, fmt, args);
|
||||
else
|
||||
DN_OS_PrintLnFV(DN_OSPrintDest_Err, fmt, args);
|
||||
}
|
||||
DN_TicketMutex_End(&os->log_mutex);
|
||||
DN_TicketMutexEnd(&logger->mutex);
|
||||
}
|
||||
|
||||
DN_API void DN_OS_LoggerF(DN_OSLogger *logger, DN_LogTypeParam type, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_OS_LoggerFV(logger, type, call_site, flags, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
DN_API void DN_OS_SetLogPrintFuncToOS()
|
||||
@@ -11537,7 +11656,6 @@ DN_API void DN_OS_SetLogPrintFuncToOS()
|
||||
DN_LogSetPrintFunc(DN_OS_LogPrint, &dn->os);
|
||||
}
|
||||
|
||||
|
||||
DN_API void *DN_OS_HeapBasicAlloc(DN_USize size)
|
||||
{
|
||||
void *result = DN_OS_MemAlloc(size, DN_ZMem_Yes);
|
||||
@@ -11714,6 +11832,7 @@ DN_API bool DN_OS_FileWrite(DN_OSFile *file, DN_Str8 buffer, DN_ErrSink *error)
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef struct DN_OSFileWriteChunker_ DN_OSFileWriteChunker_;
|
||||
struct DN_OSFileWriteChunker_
|
||||
{
|
||||
DN_ErrSink *err;
|
||||
@@ -11975,45 +12094,7 @@ DN_API bool DN_OS_PathPop(DN_OSPath *fs_path)
|
||||
return true;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathTo(DN_Arena *arena, DN_Str8 path, DN_Str8 path_separator)
|
||||
{
|
||||
DN_OSPath fs_path = {};
|
||||
DN_OS_PathAddRef(arena, &fs_path, path);
|
||||
DN_Str8 result = DN_OS_PathBuildWithSeparator(arena, &fs_path, path_separator);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathToF(DN_Arena *arena, DN_Str8 path_separator, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
||||
va_end(args);
|
||||
DN_Str8 result = DN_OS_PathTo(arena, path, path_separator);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_Path(DN_Arena *arena, DN_Str8 path)
|
||||
{
|
||||
DN_Str8 result = DN_OS_PathTo(arena, path, DN_OSPathSeperatorString);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathF(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
||||
va_end(args);
|
||||
DN_Str8 result = DN_OS_Path(arena, path);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathBuildWithSeparator(DN_Arena *arena, DN_OSPath const *fs_path, DN_Str8 path_separator)
|
||||
DN_API DN_Str8 DN_OS_PathBuildWithSeparatorAllocator(DN_Allocator allocator, DN_OSPath const *fs_path, DN_Str8 path_separator)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (!fs_path || fs_path->links_size <= 0)
|
||||
@@ -12021,7 +12102,7 @@ DN_API DN_Str8 DN_OS_PathBuildWithSeparator(DN_Arena *arena, DN_OSPath const *fs
|
||||
|
||||
// NOTE: Each link except the last one needs the path separator appended to it, '/' or '\\'
|
||||
DN_USize string_size = (fs_path->has_prefix_path_separator ? path_separator.count : 0) + fs_path->string_size + ((fs_path->links_size - 1) * path_separator.count);
|
||||
result = DN_Str8AllocArena(string_size, DN_ZMem_No, arena);
|
||||
result = DN_Str8AllocAllocator(string_size, DN_ZMem_No, allocator);
|
||||
if (result.data) {
|
||||
char *dest = result.data;
|
||||
if (fs_path->has_prefix_path_separator) {
|
||||
@@ -12045,7 +12126,88 @@ DN_API DN_Str8 DN_OS_PathBuildWithSeparator(DN_Arena *arena, DN_OSPath const *fs
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: DN_OSExec
|
||||
DN_API DN_Str8 DN_OS_PathToArena(DN_Arena *arena, DN_Str8 path, DN_Str8 path_separator)
|
||||
{
|
||||
DN_OSPath fs_path = {};
|
||||
DN_OS_PathAddRef(arena, &fs_path, path);
|
||||
DN_Allocator allocator = DN_AllocatorFromArena(arena);
|
||||
DN_Str8 result = DN_OS_PathBuildWithSeparatorAllocator(allocator, &fs_path, path_separator);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathToPool(DN_Pool *pool, DN_Str8 path, DN_Str8 path_separator)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&pool->arena, 1);
|
||||
DN_OSPath fs_path = {};
|
||||
DN_OS_PathAddRef(&scratch.arena, &fs_path, path);
|
||||
|
||||
DN_Allocator allocator = DN_AllocatorFromPool(pool);
|
||||
DN_Str8 result = DN_OS_PathBuildWithSeparatorAllocator(allocator, &fs_path, path_separator);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathToFmtArena(DN_Arena *arena, DN_Str8 path_separator, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
||||
va_end(args);
|
||||
DN_Str8 result = DN_OS_PathToArena(arena, path, path_separator);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathToFmtPool(DN_Pool *pool, DN_Str8 path_separator, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&pool->arena, 1);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
DN_Str8 result = DN_OS_PathToPool(pool, path, path_separator);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathArena(DN_Arena *arena, DN_Str8 path)
|
||||
{
|
||||
DN_Str8 result = DN_OS_PathToArena(arena, path, DN_OSPathSeparatorStr8);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathPool(DN_Pool *pool, DN_Str8 path)
|
||||
{
|
||||
DN_Str8 result = DN_OS_PathToPool(pool, path, DN_OSPathSeparatorStr8);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathFmtArena(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
||||
va_end(args);
|
||||
DN_Str8 result = DN_OS_PathArena(arena, path);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathFmtPool(DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&pool->arena, 1);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
||||
va_end(args);
|
||||
DN_Str8 result = DN_OS_PathPool(pool, path);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_OSExecResult DN_OS_Exec(DN_Str8Slice cmd_line, DN_OSExecArgs *args, DN_Arena *arena, DN_ErrSink *error)
|
||||
{
|
||||
DN_OSExecAsyncHandle async_handle = DN_OS_ExecAsync(cmd_line, args, error);
|
||||
@@ -12524,7 +12686,7 @@ DN_API DN_StackTrace DN_StackTraceFromAllocator(DN_Allocator allocator, DN_U16 l
|
||||
return result;
|
||||
|
||||
static DN_TicketMutex mutex = {};
|
||||
DN_TicketMutex_Begin(&mutex);
|
||||
DN_TicketMutexBegin(&mutex);
|
||||
|
||||
HANDLE thread = GetCurrentThread();
|
||||
result.process = GetCurrentProcess();
|
||||
@@ -12570,7 +12732,7 @@ DN_API DN_StackTrace DN_StackTraceFromAllocator(DN_Allocator allocator, DN_U16 l
|
||||
// If AddrPC.Offset == AddrReturn.Offset then we can detect recursion.
|
||||
DN_LArrayAppend(raw_frames, &raw_frames_count, frame.AddrPC.Offset);
|
||||
}
|
||||
DN_TicketMutex_End(&mutex);
|
||||
DN_TicketMutexEnd(&mutex);
|
||||
|
||||
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);
|
||||
@@ -14856,9 +15018,9 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it)
|
||||
// add those characters in this branch, so overwrite the null
|
||||
// character, add the glob and re-null terminate the buffer.
|
||||
if (needs_asterisks)
|
||||
adjusted_path = DN_OS_PathF(&scratch.arena, "%.*s*", DN_Str8PrintFmt(path));
|
||||
adjusted_path = DN_OS_PathFmtArena(&scratch.arena, "%.*s*", DN_Str8PrintFmt(path));
|
||||
else
|
||||
adjusted_path = DN_OS_PathF(&scratch.arena, "%.*s/*", DN_Str8PrintFmt(path));
|
||||
adjusted_path = DN_OS_PathFmtArena(&scratch.arena, "%.*s/*", DN_Str8PrintFmt(path));
|
||||
}
|
||||
|
||||
path16 = DN_OS_W32Str8ToStr16(&scratch.arena, adjusted_path);
|
||||
@@ -16037,6 +16199,7 @@ void DN_NET_EndFinishedRequest(DN_NETRequest *request)
|
||||
#endif // #if DN_WITH_NET
|
||||
|
||||
#if DN_WITH_NET_CURL
|
||||
typedef struct DN_NETCurlRequest DN_NETCurlRequest;
|
||||
struct DN_NETCurlRequest
|
||||
{
|
||||
void *handle;
|
||||
@@ -16055,6 +16218,7 @@ enum DN_NETCurlRingEventType
|
||||
DN_NETCurlRingEventType_DeinitRequest,
|
||||
};
|
||||
|
||||
typedef struct DN_NETCurlRingEvent_ DN_NETCurlRingEvent_;
|
||||
struct DN_NETCurlRingEvent_
|
||||
{
|
||||
DN_NETCurlRingEventType type;
|
||||
@@ -16756,6 +16920,7 @@ DN_NETResponse DN_NET_CurlWaitForAnyResponse(DN_NETCore *net, DN_Arena *arena, D
|
||||
#include <emscripten/fetch.h>
|
||||
#include <emscripten/websocket.h>
|
||||
|
||||
typedef struct DN_NETEmcWSEvent DN_NETEmcWSEvent;
|
||||
struct DN_NETEmcWSEvent
|
||||
{
|
||||
DN_NETResponseState state;
|
||||
@@ -16763,6 +16928,7 @@ struct DN_NETEmcWSEvent
|
||||
DN_NETEmcWSEvent *next;
|
||||
};
|
||||
|
||||
typedef struct DN_NETEmcCore DN_NETEmcCore;
|
||||
struct DN_NETEmcCore
|
||||
{
|
||||
DN_Pool pool;
|
||||
@@ -16770,6 +16936,7 @@ struct DN_NETEmcCore
|
||||
DN_NETRequest *free_list; // Request pool that new requests will use before allocating
|
||||
};
|
||||
|
||||
typedef struct DN_NETEmcRequest DN_NETEmcRequest;
|
||||
struct DN_NETEmcRequest
|
||||
{
|
||||
int socket;
|
||||
|
||||
+296
-120
File diff suppressed because it is too large
Load Diff
@@ -649,9 +649,9 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it)
|
||||
// add those characters in this branch, so overwrite the null
|
||||
// character, add the glob and re-null terminate the buffer.
|
||||
if (needs_asterisks)
|
||||
adjusted_path = DN_OS_PathF(&scratch.arena, "%.*s*", DN_Str8PrintFmt(path));
|
||||
adjusted_path = DN_OS_PathFmtArena(&scratch.arena, "%.*s*", DN_Str8PrintFmt(path));
|
||||
else
|
||||
adjusted_path = DN_OS_PathF(&scratch.arena, "%.*s/*", DN_Str8PrintFmt(path));
|
||||
adjusted_path = DN_OS_PathFmtArena(&scratch.arena, "%.*s/*", DN_Str8PrintFmt(path));
|
||||
}
|
||||
|
||||
path16 = DN_OS_W32Str8ToStr16(&scratch.arena, adjusted_path);
|
||||
|
||||
+275
-108
@@ -546,24 +546,24 @@ DN_API DN_CPUReport DN_CPUGetReport()
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void DN_TicketMutex_Begin(DN_TicketMutex *mutex)
|
||||
DN_API void DN_TicketMutexBegin(DN_TicketMutex *mutex)
|
||||
{
|
||||
DN_UInt ticket = DN_AtomicAddU32(&mutex->ticket, 1);
|
||||
DN_TicketMutex_BeginTicket(mutex, ticket);
|
||||
DN_TicketMutexBeginTicket(mutex, ticket);
|
||||
}
|
||||
|
||||
DN_API void DN_TicketMutex_End(DN_TicketMutex *mutex)
|
||||
DN_API void DN_TicketMutexEnd(DN_TicketMutex *mutex)
|
||||
{
|
||||
DN_AtomicAddU32(&mutex->serving, 1);
|
||||
}
|
||||
|
||||
DN_API DN_UInt DN_TicketMutex_MakeTicket(DN_TicketMutex *mutex)
|
||||
DN_API DN_UInt DN_TicketMutexMakeTicket(DN_TicketMutex *mutex)
|
||||
{
|
||||
DN_UInt result = DN_AtomicAddU32(&mutex->ticket, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API void DN_TicketMutex_BeginTicket(DN_TicketMutex const *mutex, DN_UInt ticket)
|
||||
DN_API void DN_TicketMutexBeginTicket(DN_TicketMutex const *mutex, DN_UInt ticket)
|
||||
{
|
||||
DN_AssertF(mutex->serving <= ticket,
|
||||
"Mutex skipped ticket? Was ticket generated by the correct mutex via MakeTicket? ticket = %u, "
|
||||
@@ -576,7 +576,7 @@ DN_API void DN_TicketMutex_BeginTicket(DN_TicketMutex const *mutex, DN_UInt tick
|
||||
}
|
||||
}
|
||||
|
||||
DN_API bool DN_TicketMutex_CanLock(DN_TicketMutex const *mutex, DN_UInt ticket)
|
||||
DN_API bool DN_TicketMutexCanLock(DN_TicketMutex const *mutex, DN_UInt ticket)
|
||||
{
|
||||
bool result = (ticket == mutex->serving);
|
||||
return result;
|
||||
@@ -1766,6 +1766,12 @@ DN_API void DN_ArenaDeinit(DN_Arena *arena)
|
||||
DN_MemListDeinit(arena->mem);
|
||||
}
|
||||
|
||||
DN_API bool DN_ArenaOwnsPtr(DN_Arena const *arena, void *ptr)
|
||||
{
|
||||
bool result = DN_MemListOwnsPtr(arena->mem, ptr);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Pool DN_PoolFromArena(DN_Arena *arena, DN_U8 align)
|
||||
{
|
||||
DN_Pool result = {};
|
||||
@@ -5056,7 +5062,6 @@ DN_API DN_U8x16 DN_U8x16FromPtrHex32(char const *hex, DN_USize hex_count)
|
||||
{
|
||||
DN_U8x16 result = {};
|
||||
DN_Str8 hex_trimmed = DN_Str8TrimHexPrefix(DN_Str8FromPtr(hex, hex_count));
|
||||
DN_Assert(hex_trimmed.count / 2 == sizeof result.data);
|
||||
DN_USize bytes_written = DN_PtrBytesFromStr8Hex(hex_trimmed, result.data, sizeof result.data);
|
||||
DN_Assert(bytes_written == sizeof result.data);
|
||||
return result;
|
||||
@@ -5066,7 +5071,6 @@ DN_API DN_U8x32 DN_U8x32FromPtrHex64(char const *hex, DN_USize hex_count)
|
||||
{
|
||||
DN_U8x32 result = {};
|
||||
DN_Str8 hex_trimmed = DN_Str8TrimHexPrefix(DN_Str8FromPtr(hex, hex_count));
|
||||
DN_Assert(hex_trimmed.count / 2 == sizeof result.data);
|
||||
DN_USize bytes_written = DN_PtrBytesFromStr8Hex(hex_trimmed, result.data, sizeof result.data);
|
||||
DN_Assert(bytes_written == sizeof result.data);
|
||||
return result;
|
||||
@@ -8092,6 +8096,7 @@ DN_API DN_RaycastV2 DN_RaycastLineIntersectV2(DN_V2F32 origin_a, DN_V2F32 dir_a,
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef struct DN_ArrayFindEqMemcmpContext_ DN_ArrayFindEqMemcmpContext_;
|
||||
struct DN_ArrayFindEqMemcmpContext_
|
||||
{
|
||||
DN_USize elem_size;
|
||||
@@ -9627,6 +9632,7 @@ DN_API void DN_TestVerifyBytesF(DN_TestCore *test, DN_CallSite call_site, DN_Str
|
||||
#if defined(DN_PLATFORM_WIN32) && defined(DN_COMPILER_MSVC)
|
||||
// NOTE: Taken from MSDN __cpuid example implementation
|
||||
// https://learn.microsoft.com/en-us/cpp/intrinsics/cpuid-cpuidex?view=msvc-170
|
||||
typedef struct DN_RefImplCPUReport DN_RefImplCPUReport;
|
||||
struct DN_RefImplCPUReport {
|
||||
unsigned int nIds_ = 0;
|
||||
unsigned int nExIds_ = 0;
|
||||
@@ -9789,22 +9795,22 @@ DN_API DN_TestCore DN_TestSuite(DN_Arena *arena_)
|
||||
{
|
||||
for (DN_TestScopeF(&result, "[TicketMutex] Start and stop")) {
|
||||
DN_TicketMutex mutex = {};
|
||||
DN_TicketMutex_Begin(&mutex);
|
||||
DN_TicketMutex_End(&mutex);
|
||||
DN_TicketMutexBegin(&mutex);
|
||||
DN_TicketMutexEnd(&mutex);
|
||||
DN_TestVerifyUSizeEq(&result, mutex.ticket, mutex.serving);
|
||||
}
|
||||
|
||||
for (DN_TestScopeF(&result, "[TicketMutex] Start and stop w/ advanced API")) {
|
||||
DN_TicketMutex mutex = {};
|
||||
unsigned int ticket_a = DN_TicketMutex_MakeTicket(&mutex);
|
||||
unsigned int ticket_b = DN_TicketMutex_MakeTicket(&mutex);
|
||||
DN_TestVerifyExpr(&result, DN_Cast(bool) DN_TicketMutex_CanLock(&mutex, ticket_b) == false);
|
||||
DN_TestVerifyExpr(&result, DN_Cast(bool) DN_TicketMutex_CanLock(&mutex, ticket_a) == true);
|
||||
DN_UInt ticket_a = DN_TicketMutexMakeTicket(&mutex);
|
||||
DN_UInt ticket_b = DN_TicketMutexMakeTicket(&mutex);
|
||||
DN_TestVerifyExpr(&result, DN_Cast(bool) DN_TicketMutexCanLock(&mutex, ticket_b) == false);
|
||||
DN_TestVerifyExpr(&result, DN_Cast(bool) DN_TicketMutexCanLock(&mutex, ticket_a) == true);
|
||||
|
||||
DN_TicketMutex_BeginTicket(&mutex, ticket_a);
|
||||
DN_TicketMutex_End(&mutex);
|
||||
DN_TicketMutex_BeginTicket(&mutex, ticket_b);
|
||||
DN_TicketMutex_End(&mutex);
|
||||
DN_TicketMutexBeginTicket(&mutex, ticket_a);
|
||||
DN_TicketMutexEnd(&mutex);
|
||||
DN_TicketMutexBeginTicket(&mutex, ticket_b);
|
||||
DN_TicketMutexEnd(&mutex);
|
||||
|
||||
DN_TestVerifyUSizeEq(&result, mutex.ticket, mutex.serving);
|
||||
DN_TestVerifyUSizeEq(&result, mutex.ticket, ticket_b + 1);
|
||||
@@ -11287,7 +11293,7 @@ DN_API void DN_LeakTrackAlloc_(DN_LeakTracker *leak, void *ptr, DN_USize size, b
|
||||
if (!ptr)
|
||||
return;
|
||||
|
||||
DN_TicketMutex_Begin(&leak->alloc_table_mutex);
|
||||
DN_TicketMutexBegin(&leak->alloc_table_mutex);
|
||||
|
||||
DN_Str8 stack_trace = DN_Str8FromStackTraceNowHeap(128, 3 /*skip*/);
|
||||
DN_HTable* alloc_table = &leak->alloc_table;
|
||||
@@ -11333,7 +11339,7 @@ DN_API void DN_LeakTrackAlloc_(DN_LeakTracker *leak, void *ptr, DN_USize size, b
|
||||
alloc->stack_trace = stack_trace;
|
||||
alloc->flags |= leak_permitted ? DN_LeakAllocFlag_LeakPermitted : 0;
|
||||
leak->alloc_table_bytes_allocated_for_stack_traces += alloc->stack_trace.count;
|
||||
DN_TicketMutex_End(&leak->alloc_table_mutex);
|
||||
DN_TicketMutexEnd(&leak->alloc_table_mutex);
|
||||
}
|
||||
|
||||
DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr)
|
||||
@@ -11341,7 +11347,7 @@ DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr)
|
||||
if (!ptr)
|
||||
return;
|
||||
|
||||
DN_TicketMutex_Begin(&leak->alloc_table_mutex);
|
||||
DN_TicketMutexBegin(&leak->alloc_table_mutex);
|
||||
|
||||
DN_Str8 stack_trace = DN_Str8FromStackTraceNowHeap(128, 3 /*skip*/);
|
||||
DN_HTable* alloc_table = &leak->alloc_table;
|
||||
@@ -11382,7 +11388,7 @@ DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr)
|
||||
alloc->flags |= DN_LeakAllocFlag_Freed;
|
||||
alloc->freed_stack_trace = stack_trace;
|
||||
leak->alloc_table_bytes_allocated_for_stack_traces += alloc->freed_stack_trace.count;
|
||||
DN_TicketMutex_End(&leak->alloc_table_mutex);
|
||||
DN_TicketMutexEnd(&leak->alloc_table_mutex);
|
||||
}
|
||||
|
||||
DN_API void DN_LeakDump_(DN_LeakTracker *leak)
|
||||
@@ -11444,52 +11450,150 @@ DN_API DN_Str8 DN_OS_Str8FromStr8BuilderHeap(DN_Str8Builder const *builder)
|
||||
|
||||
DN_API void DN_OS_LogPrint(DN_LogTypeParam type, void *user_data, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||
{
|
||||
DN_Assert(user_data);
|
||||
DN_OSCore *os = DN_Cast(DN_OSCore *)user_data;
|
||||
DN_OSLogger *logger = &os->logger;
|
||||
DN_OS_LoggerFV(logger, type, call_site, flags, fmt, args);
|
||||
}
|
||||
|
||||
// NOTE: Open log file for appending if requested
|
||||
DN_TicketMutex_Begin(&os->log_file_mutex);
|
||||
if (os->log_to_file && !os->log_file.handle && !os->log_file.error) {
|
||||
DN_API DN_Str8 DN_OS_LoggerGetRotateFilePath(DN_Str8 base_file_path, DN_Arena *arena, DN_USize rotate_index)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (rotate_index == 0)
|
||||
result = DN_OS_PathFmtArena(arena, "%.*s", DN_Str8PrintFmt(base_file_path));
|
||||
else
|
||||
result = DN_OS_PathFmtArena(arena, "%.*s.%zu", DN_Str8PrintFmt(base_file_path), rotate_index);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void DN_OS_LoggerSetFilePathNoMutex_(DN_OSLogger *logger, DN_Pool *pool, DN_Str8 file_path)
|
||||
{
|
||||
if (logger->file_path.data) {
|
||||
DN_AssertF(DN_MemListOwnsPtr(pool->arena->mem, logger->file_path.data),
|
||||
"If there's a pre-existing file path set in the logger, it must be deallocated by "
|
||||
" the caller and cleared. If it has been previously allocated with the exact same "
|
||||
" pool was allocated with the same pool then we will deallocate it for you.");
|
||||
DN_PoolDealloc(pool, logger->file_path.data);
|
||||
logger->file_path = {};
|
||||
}
|
||||
DN_OS_FileClose(&logger->file);
|
||||
logger->file_path = DN_OS_PathFmtPool(pool, "%.*s", DN_Str8PrintFmt(file_path));
|
||||
|
||||
// NOTE: Clear the sticky file error flag if it was set
|
||||
logger->flags &= ~DN_OSLoggerFlags_FileError;
|
||||
}
|
||||
|
||||
DN_API void DN_OS_LoggerSetFilePath(DN_OSLogger *logger, DN_Pool *pool, DN_Str8 file_path)
|
||||
{
|
||||
DN_TicketMutexBegin(&logger->file_mutex);
|
||||
DN_OS_LoggerSetFilePathNoMutex_(logger, pool, file_path);
|
||||
DN_TicketMutexEnd(&logger->file_mutex);
|
||||
}
|
||||
|
||||
static void DN_OS_DoLogFileSetupAndRotation_(DN_OSLogger *logger)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(nullptr, 0);
|
||||
DN_Str8 error = {};
|
||||
DN_TicketMutexBegin(&logger->file_mutex);
|
||||
if (logger->flags & DN_OSLoggerFlags_File) {
|
||||
|
||||
// NOTE: Set a default file path to log to if it's not been set yet
|
||||
if (logger->file_path.count == 0) {
|
||||
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));
|
||||
os->log_file = DN_OS_FileOpen(log_path, DN_OSFileOpen_CreateAlways, DN_OSFileAccess_AppendOnly, nullptr);
|
||||
DN_Str8 default_file_path = DN_OS_PathFmtArena(&scratch.arena, "%.*s/dn.log", DN_Str8PrintFmt(exe_dir));
|
||||
DN_OS_LoggerSetFilePathNoMutex_(logger, DN_TCMainPool(), default_file_path);
|
||||
}
|
||||
|
||||
// NOTE Rotate the log file if the criteria is met
|
||||
if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_FileError) && logger->rotate_every_n_bytes && logger->rotate_count) {
|
||||
DN_Assert(logger->file_path.count);
|
||||
DN_Assert(logger->rotate_every_n_bytes > 0);
|
||||
|
||||
DN_OSPathInfo file_info = DN_OS_PathInfo(logger->file_path);
|
||||
bool needs_rotate = file_info.size >= logger->rotate_every_n_bytes;
|
||||
if (needs_rotate) {
|
||||
DN_OS_FileClose(&logger->file);
|
||||
// NOTE: Loop through all the rotated log files from [rotate_count-1..1]. The rotated log
|
||||
// file at `rotate_count-1` gets deleted and `rotate_count-2` gets moved into
|
||||
// `rotate_count-1` and so forth
|
||||
for (DN_USize offset = 0; offset < (logger->rotate_count - 1); offset++) {
|
||||
DN_USize const file_index = logger->rotate_count - (offset + 1);
|
||||
DN_Str8 file_path = DN_OS_LoggerGetRotateFilePath(logger->file_path, &scratch.arena, file_index);
|
||||
DN_Str8 prev_file_path = DN_OS_LoggerGetRotateFilePath(logger->file_path, &scratch.arena, file_index - 1);
|
||||
DN_OS_FileMove(prev_file_path, file_path, true, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: After rotating, check the file size of the log file we will write to again. If the
|
||||
// file size is still greater than the rotate size, then there was an error when we
|
||||
// attempted to rotate the logs. Set the sticky file flag error to disable to logger and
|
||||
// inform the user.
|
||||
if (needs_rotate) {
|
||||
DN_OSPathInfo recheck_file_info = DN_OS_PathInfo(logger->file_path);
|
||||
if (recheck_file_info.size >= logger->rotate_every_n_bytes) {
|
||||
logger->flags |= DN_OSLoggerFlags_FileError;
|
||||
error = DN_Str8FromFmtArena(&scratch.arena, "Rotating of log files failed at (%.*s). Logging to disk is disabled", DN_Str8PrintFmt(logger->file_path));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Open the file requested by the logger if it hasn't been opened yet
|
||||
if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_FileError)) {
|
||||
if (!logger->file.handle && !logger->file.error) {
|
||||
DN_OSPathInfo file_path_info = DN_OS_PathInfo(logger->file_path);
|
||||
if (file_path_info.exists && file_path_info.type != DN_OSPathInfoType_File) {
|
||||
logger->flags |= DN_OSLoggerFlags_FileError;
|
||||
error = DN_Str8FromFmtArena(&scratch.arena, "File path to log to (%.*s) exists but is not a writable file. Logging to disk is disabled.", DN_Str8PrintFmt(logger->file_path));
|
||||
}
|
||||
|
||||
if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_FileError))
|
||||
logger->file = DN_OS_FileOpen(logger->file_path, DN_OSFileOpen_OpenAlways, DN_OSFileAccess_AppendOnly, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Set the sticky error flag on the file if opening failed. The sticky flag ensures we
|
||||
// only notify the user once of a file open failure per unique base file path
|
||||
if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_FileError)) {
|
||||
if (logger->file.error) {
|
||||
logger->flags |= DN_OSLoggerFlags_FileError;
|
||||
error = DN_Str8FromFmtArena(&scratch.arena, "Failed to open file (%.*s) for logging. Logging to disk is disabled", DN_Str8PrintFmt(logger->file_path));
|
||||
}
|
||||
}
|
||||
}
|
||||
DN_TicketMutexEnd(&logger->file_mutex);
|
||||
|
||||
// NOTE: Error is logged outside of the mutex since logging will recurse back into the OS logger
|
||||
if (error.count)
|
||||
DN_LogWarningF("%.*s", DN_Str8PrintFmt(error));
|
||||
DN_TCScratchEnd(&scratch);
|
||||
}
|
||||
DN_TicketMutex_End(&os->log_file_mutex);
|
||||
|
||||
DN_API void DN_OS_LoggerFV(DN_OSLogger *logger, DN_LogTypeParam type, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, va_list args)
|
||||
{
|
||||
DN_OS_DoLogFileSetupAndRotation_(logger);
|
||||
bool print_prefix = DN_BitIsNotSet(flags, DN_LogFlags_NoPrefix);
|
||||
char prefix_buffer[128] = {};
|
||||
DN_LogPrefixSize prefix_size = {};
|
||||
char prefix_colour_buffer[128] = {};
|
||||
DN_LogPrefixSize prefix_colour_size = {};
|
||||
if (print_prefix) {
|
||||
DN_LogStyle style = {};
|
||||
if (!os->log_no_colour) {
|
||||
style.colour = true;
|
||||
style.bold = DN_LogBold_Yes;
|
||||
// NOTE: Generate 2 variants of the style (colour and colour-less) for printing the prefix of
|
||||
// the log line
|
||||
DN_LogStyle style_colour = {};
|
||||
style_colour.bold = DN_LogBold_Yes;
|
||||
style_colour.colour = true;
|
||||
if (type.is_u32_enum) {
|
||||
switch (type.u32) {
|
||||
case DN_LogType_Debug: {
|
||||
case DN_LogType_Debug: style_colour.colour = false; style_colour.bold = DN_LogBold_No; break;
|
||||
case DN_LogType_Info: style_colour.g = 0x87; style_colour.b = 0xff; break;
|
||||
case DN_LogType_Warning: style_colour.r = 0xff; style_colour.g = 0xff; break;
|
||||
case DN_LogType_Error: style_colour.r = 0xff; break;
|
||||
}
|
||||
}
|
||||
|
||||
DN_LogStyle style = style_colour;
|
||||
style.colour = false;
|
||||
style.bold = DN_LogBold_No;
|
||||
} break;
|
||||
|
||||
case DN_LogType_Info: {
|
||||
style.g = 0x87;
|
||||
style.b = 0xff;
|
||||
} break;
|
||||
|
||||
case DN_LogType_Warning: {
|
||||
style.r = 0xff;
|
||||
style.g = 0xff;
|
||||
} break;
|
||||
|
||||
case DN_LogType_Error: {
|
||||
style.r = 0xff;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Build the log prefix
|
||||
DN_Date os_date = DN_OS_DateLocalTimeNow();
|
||||
DN_LogDate log_date = {};
|
||||
log_date.year = os_date.year;
|
||||
@@ -11498,35 +11602,50 @@ DN_API void DN_OS_LogPrint(DN_LogTypeParam type, void *user_data, DN_CallSite ca
|
||||
log_date.hour = os_date.hour;
|
||||
log_date.minute = os_date.minutes;
|
||||
log_date.second = os_date.seconds;
|
||||
prefix_size = DN_LogMakePrefix(style, type, call_site, log_date, prefix_buffer, sizeof(prefix_buffer));
|
||||
prefix_size = DN_LogMakePrefix(style, type, call_site, log_date, prefix_buffer, DN_ArrayCountU(prefix_buffer));
|
||||
prefix_colour_size = DN_LogMakePrefix(style_colour, type, call_site, log_date, prefix_colour_buffer, DN_ArrayCountU(prefix_colour_buffer));
|
||||
}
|
||||
|
||||
// NOTE: Log to disk. Note that a file handle that error-ed is a no-op in these functions so no
|
||||
// extra branching is needed to handle that.
|
||||
va_list args_copy;
|
||||
va_copy(args_copy, args);
|
||||
DN_TicketMutex_Begin(&os->log_file_mutex);
|
||||
DN_TicketMutexBegin(&logger->file_mutex);
|
||||
{
|
||||
if (print_prefix) {
|
||||
DN_OS_FileWrite(&os->log_file, DN_Str8FromPtr(prefix_buffer, prefix_size.count), nullptr);
|
||||
DN_OS_FileWriteF(&os->log_file, nullptr, "%*s ", DN_Cast(int) prefix_size.padding, "");
|
||||
DN_OS_FileWrite(&logger->file, DN_Str8FromPtr(prefix_buffer, prefix_size.count), nullptr);
|
||||
DN_OS_FileWriteF(&logger->file, nullptr, "%*s ", DN_Cast(int) prefix_size.padding, "");
|
||||
}
|
||||
DN_OS_FileWriteFV(&os->log_file, nullptr, fmt, args_copy);
|
||||
DN_OS_FileWriteFV(&logger->file, nullptr, fmt, args_copy);
|
||||
if (!DN_BitIsSet(flags, DN_LogFlags_NoNewLine))
|
||||
DN_OS_FileWrite(&os->log_file, DN_Str8Lit("\n"), nullptr);
|
||||
DN_OS_FileWrite(&logger->file, DN_Str8Lit("\n"), nullptr);
|
||||
}
|
||||
DN_TicketMutex_End(&os->log_file_mutex);
|
||||
DN_TicketMutexEnd(&logger->file_mutex);
|
||||
va_end(args_copy);
|
||||
|
||||
DN_TicketMutex_Begin(&os->log_mutex);
|
||||
{
|
||||
if (print_prefix)
|
||||
DN_TicketMutexBegin(&logger->mutex);
|
||||
if (DN_BitIsNotSet(logger->flags, DN_OSLoggerFlags_NoOutput)) {
|
||||
if (print_prefix) {
|
||||
if (DN_BitIsSet(logger->flags, DN_OSLoggerFlags_NoColour))
|
||||
DN_OS_PrintF(DN_OSPrintDest_Err, "%.*s%*s ", DN_Cast(int) prefix_size.count, prefix_buffer, DN_Cast(int) prefix_size.padding, "");
|
||||
else
|
||||
DN_OS_PrintF(DN_OSPrintDest_Err, "%.*s%*s ", DN_Cast(int) prefix_colour_size.count, prefix_colour_buffer, DN_Cast(int) prefix_colour_size.padding, "");
|
||||
}
|
||||
|
||||
if (DN_BitIsSet(flags, DN_LogFlags_NoNewLine))
|
||||
DN_OS_PrintFV(DN_OSPrintDest_Err, fmt, args);
|
||||
else
|
||||
DN_OS_PrintLnFV(DN_OSPrintDest_Err, fmt, args);
|
||||
}
|
||||
DN_TicketMutex_End(&os->log_mutex);
|
||||
DN_TicketMutexEnd(&logger->mutex);
|
||||
}
|
||||
|
||||
DN_API void DN_OS_LoggerF(DN_OSLogger *logger, DN_LogTypeParam type, DN_CallSite call_site, DN_LogFlags flags, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_OS_LoggerFV(logger, type, call_site, flags, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
DN_API void DN_OS_SetLogPrintFuncToOS()
|
||||
@@ -11535,7 +11654,6 @@ DN_API void DN_OS_SetLogPrintFuncToOS()
|
||||
DN_LogSetPrintFunc(DN_OS_LogPrint, &dn->os);
|
||||
}
|
||||
|
||||
|
||||
DN_API void *DN_OS_HeapBasicAlloc(DN_USize size)
|
||||
{
|
||||
void *result = DN_OS_MemAlloc(size, DN_ZMem_Yes);
|
||||
@@ -11712,6 +11830,7 @@ DN_API bool DN_OS_FileWrite(DN_OSFile *file, DN_Str8 buffer, DN_ErrSink *error)
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef struct DN_OSFileWriteChunker_ DN_OSFileWriteChunker_;
|
||||
struct DN_OSFileWriteChunker_
|
||||
{
|
||||
DN_ErrSink *err;
|
||||
@@ -11973,45 +12092,7 @@ DN_API bool DN_OS_PathPop(DN_OSPath *fs_path)
|
||||
return true;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathTo(DN_Arena *arena, DN_Str8 path, DN_Str8 path_separator)
|
||||
{
|
||||
DN_OSPath fs_path = {};
|
||||
DN_OS_PathAddRef(arena, &fs_path, path);
|
||||
DN_Str8 result = DN_OS_PathBuildWithSeparator(arena, &fs_path, path_separator);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathToF(DN_Arena *arena, DN_Str8 path_separator, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
||||
va_end(args);
|
||||
DN_Str8 result = DN_OS_PathTo(arena, path, path_separator);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_Path(DN_Arena *arena, DN_Str8 path)
|
||||
{
|
||||
DN_Str8 result = DN_OS_PathTo(arena, path, DN_OSPathSeperatorString);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathF(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
||||
va_end(args);
|
||||
DN_Str8 result = DN_OS_Path(arena, path);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathBuildWithSeparator(DN_Arena *arena, DN_OSPath const *fs_path, DN_Str8 path_separator)
|
||||
DN_API DN_Str8 DN_OS_PathBuildWithSeparatorAllocator(DN_Allocator allocator, DN_OSPath const *fs_path, DN_Str8 path_separator)
|
||||
{
|
||||
DN_Str8 result = {};
|
||||
if (!fs_path || fs_path->links_size <= 0)
|
||||
@@ -12019,7 +12100,7 @@ DN_API DN_Str8 DN_OS_PathBuildWithSeparator(DN_Arena *arena, DN_OSPath const *fs
|
||||
|
||||
// NOTE: Each link except the last one needs the path separator appended to it, '/' or '\\'
|
||||
DN_USize string_size = (fs_path->has_prefix_path_separator ? path_separator.count : 0) + fs_path->string_size + ((fs_path->links_size - 1) * path_separator.count);
|
||||
result = DN_Str8AllocArena(string_size, DN_ZMem_No, arena);
|
||||
result = DN_Str8AllocAllocator(string_size, DN_ZMem_No, allocator);
|
||||
if (result.data) {
|
||||
char *dest = result.data;
|
||||
if (fs_path->has_prefix_path_separator) {
|
||||
@@ -12043,7 +12124,88 @@ DN_API DN_Str8 DN_OS_PathBuildWithSeparator(DN_Arena *arena, DN_OSPath const *fs
|
||||
return result;
|
||||
}
|
||||
|
||||
// NOTE: DN_OSExec
|
||||
DN_API DN_Str8 DN_OS_PathToArena(DN_Arena *arena, DN_Str8 path, DN_Str8 path_separator)
|
||||
{
|
||||
DN_OSPath fs_path = {};
|
||||
DN_OS_PathAddRef(arena, &fs_path, path);
|
||||
DN_Allocator allocator = DN_AllocatorFromArena(arena);
|
||||
DN_Str8 result = DN_OS_PathBuildWithSeparatorAllocator(allocator, &fs_path, path_separator);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathToPool(DN_Pool *pool, DN_Str8 path, DN_Str8 path_separator)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&pool->arena, 1);
|
||||
DN_OSPath fs_path = {};
|
||||
DN_OS_PathAddRef(&scratch.arena, &fs_path, path);
|
||||
|
||||
DN_Allocator allocator = DN_AllocatorFromPool(pool);
|
||||
DN_Str8 result = DN_OS_PathBuildWithSeparatorAllocator(allocator, &fs_path, path_separator);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathToFmtArena(DN_Arena *arena, DN_Str8 path_separator, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
||||
va_end(args);
|
||||
DN_Str8 result = DN_OS_PathToArena(arena, path, path_separator);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathToFmtPool(DN_Pool *pool, DN_Str8 path_separator, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&pool->arena, 1);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
DN_Str8 result = DN_OS_PathToPool(pool, path, path_separator);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathArena(DN_Arena *arena, DN_Str8 path)
|
||||
{
|
||||
DN_Str8 result = DN_OS_PathToArena(arena, path, DN_OSPathSeparatorStr8);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathPool(DN_Pool *pool, DN_Str8 path)
|
||||
{
|
||||
DN_Str8 result = DN_OS_PathToPool(pool, path, DN_OSPathSeparatorStr8);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathFmtArena(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&arena, 1);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
||||
va_end(args);
|
||||
DN_Str8 result = DN_OS_PathArena(arena, path);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_Str8 DN_OS_PathFmtPool(DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...)
|
||||
{
|
||||
DN_TCScratch scratch = DN_TCScratchBeginArena(&pool->arena, 1);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
|
||||
va_end(args);
|
||||
DN_Str8 result = DN_OS_PathPool(pool, path);
|
||||
DN_TCScratchEnd(&scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
DN_API DN_OSExecResult DN_OS_Exec(DN_Str8Slice cmd_line, DN_OSExecArgs *args, DN_Arena *arena, DN_ErrSink *error)
|
||||
{
|
||||
DN_OSExecAsyncHandle async_handle = DN_OS_ExecAsync(cmd_line, args, error);
|
||||
@@ -12522,7 +12684,7 @@ DN_API DN_StackTrace DN_StackTraceFromAllocator(DN_Allocator allocator, DN_U16 l
|
||||
return result;
|
||||
|
||||
static DN_TicketMutex mutex = {};
|
||||
DN_TicketMutex_Begin(&mutex);
|
||||
DN_TicketMutexBegin(&mutex);
|
||||
|
||||
HANDLE thread = GetCurrentThread();
|
||||
result.process = GetCurrentProcess();
|
||||
@@ -12568,7 +12730,7 @@ DN_API DN_StackTrace DN_StackTraceFromAllocator(DN_Allocator allocator, DN_U16 l
|
||||
// If AddrPC.Offset == AddrReturn.Offset then we can detect recursion.
|
||||
DN_LArrayAppend(raw_frames, &raw_frames_count, frame.AddrPC.Offset);
|
||||
}
|
||||
DN_TicketMutex_End(&mutex);
|
||||
DN_TicketMutexEnd(&mutex);
|
||||
|
||||
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);
|
||||
@@ -12901,6 +13063,7 @@ void DN_NET_EndFinishedRequest(DN_NETRequest *request)
|
||||
#endif // #if DN_WITH_NET
|
||||
|
||||
#if DN_WITH_NET_CURL
|
||||
typedef struct DN_NETCurlRequest DN_NETCurlRequest;
|
||||
struct DN_NETCurlRequest
|
||||
{
|
||||
void *handle;
|
||||
@@ -12919,6 +13082,7 @@ enum DN_NETCurlRingEventType
|
||||
DN_NETCurlRingEventType_DeinitRequest,
|
||||
};
|
||||
|
||||
typedef struct DN_NETCurlRingEvent_ DN_NETCurlRingEvent_;
|
||||
struct DN_NETCurlRingEvent_
|
||||
{
|
||||
DN_NETCurlRingEventType type;
|
||||
@@ -13620,6 +13784,7 @@ DN_NETResponse DN_NET_CurlWaitForAnyResponse(DN_NETCore *net, DN_Arena *arena, D
|
||||
#include <emscripten/fetch.h>
|
||||
#include <emscripten/websocket.h>
|
||||
|
||||
typedef struct DN_NETEmcWSEvent DN_NETEmcWSEvent;
|
||||
struct DN_NETEmcWSEvent
|
||||
{
|
||||
DN_NETResponseState state;
|
||||
@@ -13627,6 +13792,7 @@ struct DN_NETEmcWSEvent
|
||||
DN_NETEmcWSEvent *next;
|
||||
};
|
||||
|
||||
typedef struct DN_NETEmcCore DN_NETEmcCore;
|
||||
struct DN_NETEmcCore
|
||||
{
|
||||
DN_Pool pool;
|
||||
@@ -13634,6 +13800,7 @@ struct DN_NETEmcCore
|
||||
DN_NETRequest *free_list; // Request pool that new requests will use before allocating
|
||||
};
|
||||
|
||||
typedef struct DN_NETEmcRequest DN_NETEmcRequest;
|
||||
struct DN_NETEmcRequest
|
||||
{
|
||||
int socket;
|
||||
|
||||
+295
-119
File diff suppressed because it is too large
Load Diff
@@ -65,7 +65,7 @@ static void AppendCppFileLineByLine(DN_Str8Builder *dest, DN_Str8 cpp_path)
|
||||
line = DN_Str8FromFmtArena(&scratch.arena, "%S// DN: Single header generator commented out => %S", find.start_to_before_match, DN_Str8TrimWhitespaceAround(find.match_to_end_of_buffer));
|
||||
DN_Str8 rel_include_path = DN_Str8TrimWhitespaceAround(find.after_match_to_end_of_buffer);
|
||||
DN_Str8 root_dir = DN_Str8FileDirectoryFromPath(cpp_path);
|
||||
extra_include_path = DN_OS_PathF(&scratch.arena, "%S/%S", root_dir, DN_Str8TrimSuffixSensitive(rel_include_path, DN_Str8Lit("\"")));
|
||||
extra_include_path = DN_OS_PathFmtArena(&scratch.arena, "%S/%S", root_dir, DN_Str8TrimSuffixSensitive(rel_include_path, DN_Str8Lit("\"")));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,7 +113,7 @@ int main(int argc, char **argv)
|
||||
DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
|
||||
DN_Str8 suffix = type == FileType_Header ? DN_Str8Lit("h") : DN_Str8Lit("cpp");
|
||||
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);
|
||||
DN_Str8 path = DN_OS_PathFmtArena(&scratch.arena, "%S/%S.%S", dn_root_dir, *it.data, suffix);
|
||||
AppendCppFileLineByLine(&builder, path);
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ int main(int argc, char **argv)
|
||||
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_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_PathFmtArena(&scratch.arena, "%S/dn_single_header.%S", output_dir, suffix);
|
||||
DN_ErrSink *err = DN_TCErrSinkBeginDefault();
|
||||
DN_OS_FileWriteAllSafe(single_header_path, buffer, err);
|
||||
DN_ErrSinkEndExitIfErrorF(err, -1, "Failed to write Single header file '%S'", single_header_path);
|
||||
|
||||
Reference in New Issue
Block a user