Fix single header build with updated DN lib

This commit is contained in:
2026-05-18 11:19:15 +10:00
parent 0ff24117dd
commit 0905a10f61
31 changed files with 9674 additions and 38601 deletions
+168 -131
View File
@@ -11,61 +11,59 @@
#include <unistd.h> // getpagesize
#endif
static void *DN_ArenaBasicAllocFromOSHeap(DN_USize size)
static void *DN_OS_MemFuncsHeapAllocShim_(DN_USize size)
{
void *result = DN_OS_MemAlloc(size, DN_ZMem_Yes);
return result;
}
DN_API DN_ArenaMemFuncs DN_ArenaMemFuncsGet(DN_ArenaMemFuncType type)
DN_API DN_MemFuncs DN_MemFuncsFromType(DN_MemFuncsType type)
{
DN_ArenaMemFuncs result = {};
result.type = type;
DN_MemFuncs result = {};
result.type = type;
switch (type) {
case DN_ArenaMemFuncType_Nil: break;
case DN_ArenaMemFuncType_Basic: {
result.type = DN_ArenaMemFuncType_Basic;
result.basic_alloc = DN_ArenaBasicAllocFromOSHeap;
result.basic_dealloc = DN_OS_MemDealloc;
case DN_MemFuncsType_Nil: break;
case DN_MemFuncsType_Heap: {
result.heap_alloc = DN_OS_MemFuncsHeapAllocShim_;
result.heap_dealloc = DN_OS_MemDealloc;
} break;
case DN_ArenaMemFuncType_VMem: {
case DN_MemFuncsType_Virtual: {
DN_Core *dn = DN_Get();
DN_Assert(dn->init_flags & DN_InitFlags_OS);
result.type = DN_ArenaMemFuncType_VMem;
result.vmem_page_size = dn->os.page_size;
result.vmem_reserve = DN_OS_MemReserve;
result.vmem_commit = DN_OS_MemCommit;
result.vmem_release = DN_OS_MemRelease;
result.virtual_page_size = dn->os.page_size;
result.virtual_reserve = DN_OS_MemReserve;
result.virtual_commit = DN_OS_MemCommit;
result.virtual_release = DN_OS_MemRelease;
} break;
}
return result;
}
DN_API DN_ArenaMemFuncs DN_ArenaMemFuncsGetDefaults()
DN_API DN_MemFuncs DN_MemFuncsDefault()
{
DN_Core *dn = DN_Get();
DN_ArenaMemFuncType type = DN_ArenaMemFuncType_Basic;
DN_Core *dn = DN_Get();
DN_MemFuncsType type = DN_MemFuncsType_Heap;
if (dn->os_init) {
#if !defined(DN_PLATFORM_EMSCRIPTEN)
type = DN_ArenaMemFuncType_VMem;
#endif
#if !defined(DN_PLATFORM_EMSCRIPTEN)
type = DN_MemFuncsType_Virtual;
#endif
}
DN_ArenaMemFuncs result = DN_ArenaMemFuncsGet(type);
DN_MemFuncs result = DN_MemFuncsFromType(type);
return result;
}
DN_API DN_Arena DN_ArenaFromHeap(DN_U64 size, DN_ArenaFlags flags)
DN_API DN_MemList DN_MemListFromHeap(DN_U64 size, DN_MemFlags flags)
{
DN_ArenaMemFuncs mem_funcs = DN_ArenaMemFuncsGet(DN_ArenaMemFuncType_Basic);
DN_Arena result = DN_ArenaFromMemFuncs(size, size, flags, mem_funcs);
DN_MemFuncs mem_funcs = DN_MemFuncsFromType(DN_MemFuncsType_Heap);
DN_MemList result = DN_MemListFromMemFuncs(size, size, flags, mem_funcs);
return result;
}
DN_API DN_Arena DN_ArenaFromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags)
DN_API DN_MemList DN_MemListFromVMem(DN_U64 reserve, DN_U64 commit, DN_MemFlags flags)
{
DN_ArenaMemFuncs mem_funcs = DN_ArenaMemFuncsGet(DN_ArenaMemFuncType_VMem);
DN_Arena result = DN_ArenaFromMemFuncs(reserve, commit, flags, mem_funcs);
DN_MemFuncs mem_funcs = DN_MemFuncsFromType(DN_MemFuncsType_Virtual);
DN_MemList result = DN_MemListFromMemFuncs(reserve, commit, flags, mem_funcs);
return result;
}
@@ -95,7 +93,7 @@ DN_API DN_Str8 DN_Str8PadNewLines(DN_Arena *arena, DN_Str8 src, DN_Str8 pad)
{
// TODO: Implement this without requiring TLS so it can go into base strings
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
DN_Str8Builder builder = DN_Str8BuilderFromArena(scratch.arena);
DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
DN_Str8BSplitResult split = DN_Str8BSplit(src, DN_Str8Lit("\n"));
while (split.lhs.size) {
DN_Str8BuilderAppendRef(&builder, pad);
@@ -129,7 +127,7 @@ DN_API DN_Str8 DN_Str8BuilderBuildFromHeap(DN_Str8Builder const *builder)
return result;
}
DN_API void DN_OS_LogPrint(DN_LogTypeParam type, void *user_data, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, va_list args)
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;
@@ -138,69 +136,82 @@ DN_API void DN_OS_LogPrint(DN_LogTypeParam type, void *user_data, DN_CallSite ca
DN_TicketMutex_Begin(&os->log_file_mutex);
if (os->log_to_file && !os->log_file.handle && !os->log_file.error) {
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 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));
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_TCScratchEnd(&scratch);
}
DN_TicketMutex_End(&os->log_file_mutex);
DN_LogStyle style = {};
if (!os->log_no_colour) {
style.colour = true;
style.bold = DN_LogBold_Yes;
if (type.is_u32_enum) {
switch (type.u32) {
case DN_LogType_Debug: {
style.colour = false;
style.bold = DN_LogBold_No;
} break;
bool print_prefix = DN_BitIsNotSet(flags, DN_LogFlags_NoPrefix);
char prefix_buffer[128] = {};
DN_LogPrefixSize prefix_size = {};
if (print_prefix) {
DN_LogStyle style = {};
if (!os->log_no_colour) {
style.colour = true;
style.bold = DN_LogBold_Yes;
if (type.is_u32_enum) {
switch (type.u32) {
case DN_LogType_Debug: {
style.colour = false;
style.bold = DN_LogBold_No;
} break;
case DN_LogType_Info: {
style.g = 0x87;
style.b = 0xff;
} 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_Warning: {
style.r = 0xff;
style.g = 0xff;
} break;
case DN_LogType_Error: {
style.r = 0xff;
} break;
case DN_LogType_Error: {
style.r = 0xff;
} break;
}
}
}
DN_Date os_date = DN_OS_DateLocalTimeNow();
DN_LogDate log_date = {};
log_date.year = os_date.year;
log_date.month = os_date.month;
log_date.day = os_date.day;
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));
}
DN_Date os_date = DN_OS_DateLocalTimeNow();
DN_LogDate log_date = {};
log_date.year = os_date.year;
log_date.month = os_date.month;
log_date.day = os_date.day;
log_date.hour = os_date.hour;
log_date.minute = os_date.minutes;
log_date.second = os_date.seconds;
char prefix_buffer[128] = {};
DN_LogPrefixSize prefix_size = DN_LogMakePrefix(style, type, call_site, log_date, prefix_buffer, sizeof(prefix_buffer));
va_list args_copy;
va_copy(args_copy, args);
DN_TicketMutex_Begin(&os->log_file_mutex);
{
DN_OS_FileWrite(&os->log_file, DN_Str8FromPtr(prefix_buffer, prefix_size.size), nullptr);
DN_OS_FileWriteF(&os->log_file, nullptr, "%*s ", DN_Cast(int)prefix_size.padding, "");
if (print_prefix) {
DN_OS_FileWrite(&os->log_file, DN_Str8FromPtr(prefix_buffer, prefix_size.size), nullptr);
DN_OS_FileWriteF(&os->log_file, nullptr, "%*s ", DN_Cast(int) prefix_size.padding, "");
}
DN_OS_FileWriteFV(&os->log_file, nullptr, fmt, args_copy);
DN_OS_FileWrite(&os->log_file, DN_Str8Lit("\n"), nullptr);
if (!DN_BitIsSet(flags, DN_LogFlags_NoNewLine))
DN_OS_FileWrite(&os->log_file, DN_Str8Lit("\n"), nullptr);
}
DN_TicketMutex_End(&os->log_file_mutex);
va_end(args_copy);
DN_OSPrintDest dest = (type.is_u32_enum && type.u32 == DN_LogType_Error) ? DN_OSPrintDest_Err : DN_OSPrintDest_Out;
DN_OS_Print(dest, DN_Str8FromPtr(prefix_buffer, prefix_size.size));
DN_OS_PrintF(dest, "%*s ", DN_Cast(int)prefix_size.padding, "");
DN_OS_PrintLnFV(dest, fmt, args);
DN_TicketMutex_Begin(&os->log_mutex);
{
if (print_prefix)
DN_OS_PrintF(DN_OSPrintDest_Err, "%.*s%*s ", DN_Cast(int) prefix_size.size, prefix_buffer, DN_Cast(int) prefix_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_API void DN_OS_SetLogPrintFuncToOS()
@@ -239,11 +250,11 @@ DN_API DN_Str8 DN_OS_EXEDir(DN_Arena *arena)
DN_Str8 result = {};
if (!arena)
return result;
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
DN_Str8 exe_path = DN_OS_EXEPath(scratch.arena);
DN_Str8 separators[] = {DN_Str8Lit("/"), DN_Str8Lit("\\")};
DN_Str8BSplitResult split = DN_Str8BSplitLastArray(exe_path, separators, DN_ArrayCountU(separators));
result = DN_Str8FromStr8Arena(arena, split.lhs);
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
DN_Str8 exe_path = DN_OS_EXEPath(&scratch.arena);
DN_Str8 separators[] = {DN_Str8Lit("/"), DN_Str8Lit("\\")};
DN_Str8BSplitResult split = DN_Str8BSplitLastArray(exe_path, separators, DN_ArrayCountU(separators));
result = DN_Str8FromStr8Arena(split.lhs, arena);
DN_TCScratchEnd(&scratch);
return result;
}
@@ -388,7 +399,7 @@ DN_API bool DN_OS_FileWriteF(DN_OSFile *file, DN_ErrSink *error, DN_FMT_ATTRIB c
return result;
}
DN_API DN_Str8 DN_OS_FileReadAll(DN_Allocator alloc_type, void *allocator, DN_Str8 path, DN_ErrSink *err)
DN_API DN_Str8 DN_OS_FileReadAll(DN_Allocator allocator, DN_Str8 path, DN_ErrSink *err)
{
// NOTE: Query file size
DN_Str8 result = {};
@@ -399,14 +410,14 @@ DN_API DN_Str8 DN_OS_FileReadAll(DN_Allocator alloc_type, void *allocator, DN_St
}
// NOTE: Allocate
DN_ArenaTempMem arena_tmp = {};
if (alloc_type == DN_Allocator_Arena) {
DN_Arena *arena = DN_Cast(DN_Arena *) allocator;
arena_tmp = DN_ArenaTempMemBegin(arena);
result = DN_Str8AllocArena(arena, path_info.size, DN_ZMem_No);
DN_Arena temp_arena = {};
if (allocator.type == DN_AllocatorType_Arena) {
DN_Arena *arena = DN_Cast(DN_Arena *) allocator.context;
temp_arena = DN_ArenaTempBeginFromArena(arena);
result = DN_Str8AllocArena(path_info.size, DN_ZMem_No, &temp_arena);
} else {
DN_Pool *pool = DN_Cast(DN_Pool *) allocator;
result = DN_Str8AllocPool(pool, path_info.size);
DN_Pool *pool = DN_Cast(DN_Pool *) allocator.context;
result = DN_Str8AllocPool(path_info.size, pool);
}
if (!result.data) {
@@ -416,31 +427,41 @@ DN_API DN_Str8 DN_OS_FileReadAll(DN_Allocator alloc_type, void *allocator, DN_St
}
// NOTE: Read all
DN_OSFile file = DN_OS_FileOpen(path, DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_Read, err);
DN_OSFileRead read = DN_OS_FileRead(&file, result.data, result.size, err);
if (file.error || !read.success) {
if (alloc_type == DN_Allocator_Arena) {
DN_ArenaTempMemEnd(arena_tmp);
} else {
DN_Pool *pool = DN_Cast(DN_Pool *) allocator;
DN_OSFile file = DN_OS_FileOpen(path, DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_Read, err);
DN_OSFileRead read = DN_OS_FileRead(&file, result.data, result.size, err);
bool failed = file.error || !read.success;
if (allocator.type == DN_AllocatorType_Arena) {
DN_ArenaTempEnd(&temp_arena, failed ? DN_ArenaReset_Yes : DN_ArenaReset_No);
} else {
if (failed) {
DN_Pool *pool = DN_Cast(DN_Pool *) allocator.context;
DN_PoolDealloc(pool, result.data);
}
result = {};
}
if (failed)
result = {};
DN_OS_FileClose(&file);
return result;
}
DN_API DN_Str8 DN_OS_FileReadAllArena(DN_Arena *arena, DN_Str8 path, DN_ErrSink *err)
{
DN_Str8 result = DN_OS_FileReadAll(DN_Allocator_Arena, arena, path, err);
DN_Allocator allocator = {};
allocator.type = DN_AllocatorType_Arena;
allocator.context = arena;
DN_Str8 result = DN_OS_FileReadAll(allocator, path, err);
return result;
}
DN_API DN_Str8 DN_OS_FileReadAllPool(DN_Pool *pool, DN_Str8 path, DN_ErrSink *err)
{
DN_Str8 result = DN_OS_FileReadAll(DN_Allocator_Pool, pool, path, err);
DN_Allocator allocator = {};
allocator.type = DN_AllocatorType_Pool;
allocator.context = pool;
DN_Str8 result = DN_OS_FileReadAll(allocator, path, err);
return result;
}
@@ -454,9 +475,9 @@ DN_API bool DN_OS_FileWriteAll(DN_Str8 path, DN_Str8 buffer, DN_ErrSink *error)
DN_API bool DN_OS_FileWriteAllFV(DN_Str8 file_path, DN_ErrSink *error, DN_FMT_ATTRIB char const *fmt, va_list args)
{
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str8 buffer = DN_Str8FromFmtVArena(scratch.arena, fmt, args);
bool result = DN_OS_FileWriteAll(file_path, buffer, error);
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str8 buffer = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
bool result = DN_OS_FileWriteAll(file_path, buffer, error);
DN_TCScratchEnd(&scratch);
return result;
}
@@ -472,8 +493,8 @@ DN_API bool DN_OS_FileWriteAllF(DN_Str8 file_path, DN_ErrSink *error, DN_FMT_ATT
DN_API bool DN_OS_FileWriteAllSafe(DN_Str8 path, DN_Str8 buffer, DN_ErrSink *error)
{
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str8 tmp_path = DN_Str8FromFmtArena(scratch.arena, "%.*s.tmp", DN_Str8PrintFmt(path));
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str8 tmp_path = DN_Str8FromFmtArena(&scratch.arena, "%.*s.tmp", DN_Str8PrintFmt(path));
if (!DN_OS_FileWriteAll(tmp_path, buffer, error)) {
DN_TCScratchEnd(&scratch);
return false;
@@ -492,9 +513,9 @@ DN_API bool DN_OS_FileWriteAllSafe(DN_Str8 path, DN_Str8 buffer, DN_ErrSink *err
DN_API bool DN_OS_FileWriteAllSafeFV(DN_Str8 path, DN_ErrSink *error, DN_FMT_ATTRIB char const *fmt, va_list args)
{
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str8 buffer = DN_Str8FromFmtVArena(scratch.arena, fmt, args);
bool result = DN_OS_FileWriteAllSafe(path, buffer, error);
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str8 buffer = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
bool result = DN_OS_FileWriteAllSafe(path, buffer, error);
DN_TCScratchEnd(&scratch);
return result;
}
@@ -507,6 +528,17 @@ DN_API bool DN_OS_FileWriteAllSafeF(DN_Str8 path, DN_ErrSink *error, DN_FMT_ATTR
return result;
}
DN_API DN_Str8 DN_OS_Str8FromPathInfoType(DN_OSPathInfoType type)
{
DN_Str8 result = DN_Str8Lit("BAD PATH INFO TYPE");
switch(type) {
case DN_OSPathInfoType_Unknown: result = DN_Str8Lit("Unknown"); break;
case DN_OSPathInfoType_Directory: result = DN_Str8Lit("Directory"); break;
case DN_OSPathInfoType_File: result = DN_Str8Lit("File"); break;
}
return result;
}
DN_API bool DN_OS_PathAddRef(DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path)
{
if (!arena || !fs_path || path.size == 0)
@@ -552,7 +584,7 @@ DN_API bool DN_OS_PathAddRef(DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path)
DN_API bool DN_OS_PathAdd(DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path)
{
DN_Str8 copy = DN_Str8FromStr8Arena(arena, path);
DN_Str8 copy = DN_Str8FromStr8Arena(path, arena);
bool result = copy.size ? true : DN_OS_PathAddRef(arena, fs_path, copy);
return result;
}
@@ -601,7 +633,7 @@ DN_API DN_Str8 DN_OS_PathToF(DN_Arena *arena, DN_Str8 path_separator, DN_FMT_ATT
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
va_list args;
va_start(args, fmt);
DN_Str8 path = DN_Str8FromFmtVArena(scratch.arena, fmt, args);
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);
@@ -619,7 +651,7 @@ DN_API DN_Str8 DN_OS_PathF(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...)
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
va_list args;
va_start(args, fmt);
DN_Str8 path = DN_Str8FromFmtVArena(scratch.arena, fmt, args);
DN_Str8 path = DN_Str8FromFmtVArena(&scratch.arena, fmt, args);
va_end(args);
DN_Str8 result = DN_OS_Path(arena, path);
DN_TCScratchEnd(&scratch);
@@ -634,7 +666,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.size : 0) + fs_path->string_size + ((fs_path->links_size - 1) * path_separator.size);
result = DN_Str8AllocArena(arena, string_size, DN_ZMem_No);
result = DN_Str8AllocArena(string_size, DN_ZMem_No, arena);
if (result.data) {
char *dest = result.data;
if (fs_path->has_prefix_path_separator) {
@@ -683,7 +715,7 @@ DN_API DN_OSExecResult DN_OS_ExecOrAbort(DN_Str8Slice cmd_line, DN_OSExecArgs *a
static void DN_OS_ThreadExecute_(void *user_context)
{
DN_OSThread *thread = DN_Cast(DN_OSThread *) user_context;
DN_ArenaMemFuncs mem_funcs = DN_ArenaMemFuncsGetDefaults();
DN_MemFuncs mem_funcs = DN_MemFuncsDefault();
DN_TCInitFromMemFuncs(&thread->context, thread->thread_id, /*args=*/nullptr, mem_funcs);
DN_TCEquip(&thread->context);
if (thread->is_lane_set) {
@@ -800,9 +832,9 @@ DN_API void DN_OS_HttpRequestWait(DN_OSHttpResponse *response)
DN_API DN_OSHttpResponse DN_OS_HttpRequest(DN_Arena *arena, DN_Str8 host, DN_Str8 path, DN_OSHttpRequestSecure secure, DN_Str8 method, DN_Str8 body, DN_Str8 headers)
{
// TODO(doyle): Revise the memory allocation and its lifetime
DN_OSHttpResponse result = {};
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
result.scratch_arena = scratch.arena;
DN_OSHttpResponse result = {};
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
result.scratch_arena = scratch.arena;
DN_OS_HttpRequestAsync(&result, arena, host, path, secure, method, body, headers);
DN_OS_HttpRequestWait(&result);
@@ -899,13 +931,15 @@ DN_API void DN_OS_PrintFStyle(DN_OSPrintDest dest, DN_LogStyle style, DN_FMT_ATT
DN_API void DN_OS_PrintStyle(DN_OSPrintDest dest, DN_LogStyle style, DN_Str8 string)
{
if (string.data && string.size) {
if (style.colour)
DN_OS_Print(dest, DN_LogColourEscapeCodeStr8FromRGB(DN_LogColourType_Fg, style.r, style.g, style.b));
if (style.colour) {
DN_Str8x32 colour = DN_Str8x32FromANSIColourCodeU8RGB(DN_ANSIColourMode_Fg, style.r, style.g, style.b);
DN_OS_Print(dest, DN_Str8FromStruct(&colour));
}
if (style.bold == DN_LogBold_Yes)
DN_OS_Print(dest, DN_Str8Lit(DN_LogBoldEscapeCode));
DN_OS_Print(dest, DN_Str8Lit(DN_ANSICodeBoldLit));
DN_OS_Print(dest, string);
if (style.colour || style.bold == DN_LogBold_Yes)
DN_OS_Print(dest, DN_Str8Lit(DN_LogResetEscapeCode));
DN_OS_Print(dest, DN_Str8Lit(DN_ANSICodeResetLit));
}
}
@@ -930,13 +964,15 @@ DN_API void DN_OS_PrintFV(DN_OSPrintDest dest, DN_FMT_ATTRIB char const *fmt, va
DN_API void DN_OS_PrintFVStyle(DN_OSPrintDest dest, DN_LogStyle style, DN_FMT_ATTRIB char const *fmt, va_list args)
{
if (fmt) {
if (style.colour)
DN_OS_Print(dest, DN_LogColourEscapeCodeStr8FromRGB(DN_LogColourType_Fg, style.r, style.g, style.b));
if (style.colour) {
DN_Str8x32 colour = DN_Str8x32FromANSIColourCodeU8RGB(DN_ANSIColourMode_Fg, style.r, style.g, style.b);
DN_OS_Print(dest, DN_Str8FromStruct(&colour));
}
if (style.bold == DN_LogBold_Yes)
DN_OS_Print(dest, DN_Str8Lit(DN_LogBoldEscapeCode));
DN_OS_Print(dest, DN_Str8Lit(DN_ANSICodeBoldLit));
DN_OS_PrintFV(dest, fmt, args);
if (style.colour || style.bold == DN_LogBold_Yes)
DN_OS_Print(dest, DN_Str8Lit(DN_LogResetEscapeCode));
DN_OS_Print(dest, DN_Str8Lit(DN_ANSICodeResetLit));
}
}
@@ -1166,8 +1202,8 @@ DN_API DN_StackTraceWalkResult DN_StackTraceWalk(DN_Arena *arena, DN_U16 limit)
w32->sym_initialised = true;
SymSetOptions(SYMOPT_LOAD_LINES);
if (!SymInitialize(result.process, nullptr /*UserSearchPath*/, true /*fInvadeProcess*/)) {
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
DN_OSW32Error error = DN_OS_W32LastError(scratch.arena);
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
DN_OSW32Error error = DN_OS_W32LastError(&scratch.arena);
DN_LogErrorF("SymInitialize failed, stack trace can not be generated (%lu): %.*s\n", error.code, DN_Str8PrintFmt(error.msg));
DN_TCScratchEnd(&scratch);
}
@@ -1246,8 +1282,8 @@ DN_API DN_Str8 DN_StackTraceWalkResultToStr8(DN_Arena *arena, DN_StackTraceWalkR
if (!walk || !arena)
return result;
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
DN_Str8Builder builder = DN_Str8BuilderFromArena(scratch.arena);
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
DN_Str8Builder builder = DN_Str8BuilderFromArena(&scratch.arena);
DN_StackTraceAddWalkToStr8Builder(walk, &builder, skip);
result = DN_Str8BuilderBuild(&builder, arena);
DN_TCScratchEnd(&scratch);
@@ -1256,9 +1292,9 @@ DN_API DN_Str8 DN_StackTraceWalkResultToStr8(DN_Arena *arena, DN_StackTraceWalkR
DN_API DN_Str8 DN_StackTraceWalkStr8(DN_Arena *arena, DN_U16 limit, DN_U16 skip)
{
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
DN_StackTraceWalkResult walk = DN_StackTraceWalk(scratch.arena, limit);
DN_Str8 result = DN_StackTraceWalkResultToStr8(arena, &walk, skip);
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
DN_StackTraceWalkResult walk = DN_StackTraceWalk(&scratch.arena, limit);
DN_Str8 result = DN_StackTraceWalkResultToStr8(arena, &walk, skip);
DN_TCScratchEnd(&scratch);
return result;
}
@@ -1267,12 +1303,13 @@ DN_API DN_Str8 DN_StackTraceWalkStr8FromHeap(DN_U16 limit, DN_U16 skip)
{
// NOTE: We don't use WalkResultToStr8 because that uses the TLS arenas which
// does not use the OS heap.
DN_Arena arena = DN_ArenaFromHeap(DN_Kilobytes(64), DN_ArenaFlags_NoAllocTrack);
DN_MemList mem = DN_MemListFromHeap(DN_Kilobytes(64), DN_MemFlags_NoAllocTrack);
DN_Arena arena = DN_ArenaFromMemList(&mem);
DN_Str8Builder builder = DN_Str8BuilderFromArena(&arena);
DN_StackTraceWalkResult walk = DN_StackTraceWalk(&arena, limit);
DN_StackTraceAddWalkToStr8Builder(&walk, &builder, skip);
DN_Str8 result = DN_Str8BuilderBuildFromHeap(&builder);
DN_ArenaDeinit(&arena);
DN_MemListDeinit(&mem);
return result;
}
@@ -1283,9 +1320,9 @@ DN_API DN_StackTraceFrameSlice DN_StackTraceGetFrames(DN_Arena *arena, DN_U16 li
return result;
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
DN_StackTraceWalkResult walk = DN_StackTraceWalk(scratch.arena, limit);
DN_StackTraceWalkResult walk = DN_StackTraceWalk(&scratch.arena, limit);
if (walk.size) {
if (DN_ISliceAllocArena(DN_StackTraceFrameSlice, &result, walk.size, DN_ZMem_No, arena)) {
if (DN_ISliceAllocArena(&result, walk.size, DN_ZMem_No, arena)) {
DN_USize slice_index = 0;
for (DN_StackTraceWalkResultIterator it = {}; DN_StackTraceWalkResultIterate(&it, &walk);)
result.data[slice_index++] = DN_StackTraceRawFrameToFrame(arena, it.raw_frame);
@@ -1345,7 +1382,7 @@ DN_API DN_StackTraceFrame DN_StackTraceRawFrameToFrame(DN_Arena *arena, DN_Stack
DN_API void DN_StackTracePrint(DN_U16 limit)
{
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_StackTraceFrameSlice stack_trace = DN_StackTraceGetFrames(scratch.arena, limit);
DN_StackTraceFrameSlice stack_trace = DN_StackTraceGetFrames(&scratch.arena, limit);
for (DN_ForItSize(it, DN_StackTraceFrame, stack_trace.data, stack_trace.count)) {
DN_StackTraceFrame frame = *it.data;
DN_OS_PrintErrLnF("%.*s(%I64u): %.*s", DN_Str8PrintFmt(frame.file_name), frame.line_number, DN_Str8PrintFmt(frame.function_name));
+9 -6
View File
@@ -243,7 +243,7 @@ struct DN_OSHttpResponse
// Synchronous HTTP response uses the TLS scratch arena whereas async
// calls use their own dedicated arena.
DN_Arena tmp_arena;
DN_Arena *scratch_arena;
DN_Arena scratch_arena;
DN_Str8Builder builder;
DN_OSSemaphore on_complete_semaphore;
@@ -265,6 +265,7 @@ struct DN_OSCore
DN_OSFile log_file; // TODO(dn): Hmmm, how should we do this... ?
DN_TicketMutex log_file_mutex; // Is locked when instantiating the log_file for the first time
bool log_no_colour; // Disable colours in the logging output
DN_TicketMutex log_mutex;
// NOTE: OS
DN_U32 logical_processor_count;
@@ -280,6 +281,7 @@ struct DN_OSCore
DN_U64 mem_allocs_total;
DN_U64 mem_allocs_frame; // Total OS heap allocs since the last 'DN_Core_FrameBegin' was invoked
DN_MemList mem;
DN_Arena arena;
void *platform_context;
};
@@ -291,10 +293,10 @@ struct DN_OSDiskSpace
DN_U64 size;
};
DN_API DN_ArenaMemFuncs DN_ArenaMemFuncsGet (DN_ArenaMemFuncType type);
DN_API DN_ArenaMemFuncs DN_ArenaMemFuncsGetDefaults ();
DN_API DN_Arena DN_ArenaFromHeap (DN_U64 size, DN_ArenaFlags flags);
DN_API DN_Arena DN_ArenaFromVMem (DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags);
DN_API DN_MemFuncs DN_MemFuncsFromType (DN_MemFuncsType type);
DN_API DN_MemFuncs DN_MemFuncsDefault ();
DN_API DN_MemList DN_MemListFromHeap (DN_U64 size, DN_MemFlags flags);
DN_API DN_MemList DN_MemListFromVMem (DN_U64 reserve, DN_U64 commit, DN_MemFlags flags);
DN_API DN_Str8 DN_Str8FromHeapF (DN_FMT_ATTRIB char const *fmt, ...);
@@ -367,6 +369,7 @@ DN_API bool DN_OS_FileWriteAllSafe (D
DN_API bool DN_OS_FileWriteAllSafeFV (DN_Str8 path, DN_ErrSink *err, DN_FMT_ATTRIB char const *fmt, va_list args);
DN_API bool DN_OS_FileWriteAllSafeF (DN_Str8 path, DN_ErrSink *err, DN_FMT_ATTRIB char const *fmt, ...);
DN_API DN_Str8 DN_OS_Str8FromPathInfoType (DN_OSPathInfoType type);
DN_API DN_OSPathInfo DN_OS_PathInfo (DN_Str8 path);
DN_API bool DN_OS_PathIsOlderThan (DN_Str8 file, DN_Str8 check_against);
DN_API bool DN_OS_PathDelete (DN_Str8 path);
@@ -419,7 +422,7 @@ DN_API void DN_OS_ConditionVariableSignal (D
DN_API void DN_OS_ConditionVariableBroadcast (DN_OSConditionVariable *cv);
DN_API bool DN_OS_ThreadInit (DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSThreadLane *lane, void *user_context);
DN_API bool DN_OS_ThreadJoin (DN_OSThread *thread);
DN_API bool DN_OS_ThreadJoin (DN_OSThread *thread, DN_TCDeinitArenas deinit_arenas);
DN_API DN_U32 DN_OS_ThreadID ();
DN_API void DN_OS_ThreadSetNameFmt (char const *fmt, ...);
+3 -3
View File
@@ -1333,7 +1333,7 @@ DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSTh
return result;
}
DN_API bool DN_OS_ThreadJoin(DN_OSThread *thread)
DN_API bool DN_OS_ThreadJoin(DN_OSThread *thread, DN_TCDeinitArenas deinit_arenas)
{
bool result = false;
if (thread && thread->handle) {
@@ -1344,6 +1344,7 @@ DN_API bool DN_OS_ThreadJoin(DN_OSThread *thread)
result = pthread_join(thread_id, &return_val) == 0;
thread->handle = {};
thread->thread_id = {};
DN_TCDeinit(&thread->context, deinit_arenas);
}
return result;
}
@@ -1535,8 +1536,7 @@ DN_API void DN_OS_HttpRequestAsync(DN_OSHttpResponse *response,
return;
response->arena = arena;
response->builder.arena =
response->scratch_arena ? response->scratch_arena : &response->tmp_arena;
response->builder.arena = response->scratch_arena ? response->scratch_arena : &response->tmp_arena;
DN_Arena *scratch = response->scratch_arena;
DN_TCScratch scratch_ = DN_TCScratchBegin(&arena, 1);
+108 -116
View File
@@ -209,9 +209,9 @@ DN_API void DN_OS_GenBytesSecure(void *buffer, DN_U32 size)
DN_API DN_OSDiskSpace DN_OS_DiskSpace(DN_Str8 path)
{
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_OSDiskSpace result = {};
DN_Str16 path16 = DN_OS_W32Str8ToStr16(scratch.arena, path);
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_OSDiskSpace result = {};
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
ULARGE_INTEGER free_bytes_avail_to_caller;
ULARGE_INTEGER total_number_of_bytes;
@@ -233,9 +233,9 @@ DN_API DN_OSDiskSpace DN_OS_DiskSpace(DN_Str8 path)
DN_API bool DN_OS_SetEnvVar(DN_Str8 name, DN_Str8 value)
{
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str16 name16 = DN_OS_W32Str8ToStr16(scratch.arena, name);
DN_Str16 value16 = DN_OS_W32Str8ToStr16(scratch.arena, value);
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str16 name16 = DN_OS_W32Str8ToStr16(&scratch.arena, name);
DN_Str16 value16 = DN_OS_W32Str8ToStr16(&scratch.arena, value);
bool result = SetEnvironmentVariableW(name16.data, value16.data) != 0;
DN_TCScratchEnd(&scratch);
return result;
@@ -246,8 +246,8 @@ DN_API DN_Str8 DN_OS_EXEPath(DN_Arena *arena)
DN_Str8 result = {};
if (!arena)
return result;
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
DN_Str16 exe_dir16 = DN_OS_W32EXEPathW(scratch.arena);
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
DN_Str16 exe_dir16 = DN_OS_W32EXEPathW(&scratch.arena);
result = DN_OS_W32Str16ToStr8(arena, exe_dir16);
DN_TCScratchEnd(&scratch);
return result;
@@ -286,15 +286,15 @@ static DN_U64 DN_OS_W32FileTimeToSeconds_(FILETIME const *time)
DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink *err)
{
bool result = false;
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str16 src16 = DN_OS_W32Str8ToStr16(scratch.arena, src);
DN_Str16 dest16 = DN_OS_W32Str8ToStr16(scratch.arena, dest);
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str16 src16 = DN_OS_W32Str8ToStr16(&scratch.arena, src);
DN_Str16 dest16 = DN_OS_W32Str8ToStr16(&scratch.arena, dest);
int fail_if_exists = overwrite == false;
result = CopyFileW(src16.data, dest16.data, fail_if_exists) != 0;
if (!result) {
DN_OSW32Error win_error = DN_OS_W32LastError(scratch.arena);
DN_OSW32Error win_error = DN_OS_W32LastError(&scratch.arena);
DN_ErrSinkAppendF(err,
win_error.code,
"Failed to copy file '%.*s' to '%.*s': (%u) %.*s",
@@ -311,8 +311,8 @@ DN_API bool DN_OS_FileMove(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink
{
bool result = false;
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str16 src16 = DN_OS_W32Str8ToStr16(scratch.arena, src);
DN_Str16 dest16 = DN_OS_W32Str8ToStr16(scratch.arena, dest);
DN_Str16 src16 = DN_OS_W32Str8ToStr16(&scratch.arena, src);
DN_Str16 dest16 = DN_OS_W32Str8ToStr16(&scratch.arena, dest);
unsigned long flags = MOVEFILE_COPY_ALLOWED;
if (overwrite)
@@ -320,7 +320,7 @@ DN_API bool DN_OS_FileMove(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink
result = MoveFileExW(src16.data, dest16.data, flags) != 0;
if (!result) {
DN_OSW32Error win_error = DN_OS_W32LastError(scratch.arena);
DN_OSW32Error win_error = DN_OS_W32LastError(&scratch.arena);
DN_ErrSinkAppendF(err,
win_error.code,
"Failed to move file '%.*s' to '%.*s': (%u) %.*s",
@@ -333,7 +333,7 @@ DN_API bool DN_OS_FileMove(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_ErrSink
return result;
}
DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path, DN_OSFileOpen open_mode, DN_U32 access, DN_ErrSink *err)
DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path, DN_OSFileOpen open_mode, DN_OSFileAccess access, DN_ErrSink *err)
{
DN_OSFile result = {};
if (path.size == 0 || path.size <= 0)
@@ -366,18 +366,18 @@ DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path, DN_OSFileOpen open_mode, DN_U32 ac
access_mode |= GENERIC_EXECUTE;
}
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str16 path16 = DN_OS_W32Str8ToStr16(scratch.arena, path);
void *handle = CreateFileW(/*LPCWSTR lpFileName*/ path16.data,
/*DWORD dwDesiredAccess*/ access_mode,
/*DWORD dwShareMode*/ FILE_SHARE_READ | FILE_SHARE_WRITE,
/*LPSECURITY_ATTRIBUTES lpSecurityAttributes*/ nullptr,
/*DWORD dwCreationDisposition*/ create_flag,
/*DWORD dwFlagsAndAttributes*/ FILE_ATTRIBUTE_NORMAL,
/*HANDLE hTemplateFile*/ nullptr);
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
void *handle = CreateFileW(/*LPCWSTR lpFileName*/ path16.data,
/*DWORD dwDesiredAccess*/ access_mode,
/*DWORD dwShareMode*/ FILE_SHARE_READ | FILE_SHARE_WRITE,
/*LPSECURITY_ATTRIBUTES lpSecurityAttributes*/ nullptr,
/*DWORD dwCreationDisposition*/ create_flag,
/*DWORD dwFlagsAndAttributes*/ FILE_ATTRIBUTE_NORMAL,
/*HANDLE hTemplateFile*/ nullptr);
if (handle == INVALID_HANDLE_VALUE) {
DN_OSW32Error win_error = DN_OS_W32LastError(scratch.arena);
DN_OSW32Error win_error = DN_OS_W32LastError(&scratch.arena);
result.error = true;
DN_ErrSinkAppendF(err, win_error.code, "Failed to open file at '%.*s': '%.*s'", DN_Str8PrintFmt(path), DN_Str8PrintFmt(win_error.msg));
DN_TCScratchEnd(&scratch);
@@ -414,14 +414,14 @@ DN_API DN_OSFileRead DN_OS_FileRead(DN_OSFile *file, void *buffer, DN_USize size
/*LPDWORD lpNumberOfByesRead*/ &bytes_read,
/*LPOVERLAPPED lpOverlapped*/ nullptr);
if (read_result == 0) {
DN_OSW32Error win_error = DN_OS_W32LastError(scratch.arena);
DN_OSW32Error win_error = DN_OS_W32LastError(&scratch.arena);
DN_ErrSinkAppendF(err, win_error.code, "Failed to read data from file: (%u) %.*s", win_error.code, DN_Str8PrintFmt(win_error.msg));
DN_TCScratchEnd(&scratch);
return result;
}
if (bytes_read != size) {
DN_OSW32Error win_error = DN_OS_W32LastError(scratch.arena);
DN_OSW32Error win_error = DN_OS_W32LastError(&scratch.arena);
DN_ErrSinkAppendF(
err,
win_error.code,
@@ -455,9 +455,9 @@ DN_API bool DN_OS_FileWritePtr(DN_OSFile *file, void const *buffer, DN_USize siz
}
if (!result) {
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_OSW32Error win_error = DN_OS_W32LastError(scratch.arena);
DN_Str8x32 buffer_size_str8 = DN_ByteCountStr8x32(size);
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_OSW32Error win_error = DN_OS_W32LastError(&scratch.arena);
DN_Str8x32 buffer_size_str8 = DN_ByteCountStr8x32(size);
DN_ErrSinkAppendF(err, win_error.code, "Failed to write buffer (%.*s) to file handle: %.*s", DN_Str8PrintFmt(buffer_size_str8), DN_Str8PrintFmt(win_error.msg));
DN_TCScratchEnd(&scratch);
}
@@ -471,8 +471,8 @@ DN_API bool DN_OS_FileFlush(DN_OSFile *file, DN_ErrSink *err)
BOOL result = FlushFileBuffers(DN_Cast(HANDLE) file->handle);
if (!result) {
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_OSW32Error win_error = DN_OS_W32LastError(scratch.arena);
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_OSW32Error win_error = DN_OS_W32LastError(&scratch.arena);
DN_ErrSinkAppendF(err, win_error.code, "Failed to flush file buffer to disk: %.*s", DN_Str8PrintFmt(win_error.msg));
DN_TCScratchEnd(&scratch);
}
@@ -494,8 +494,8 @@ DN_API DN_OSPathInfo DN_OS_PathInfo(DN_Str8 path)
if (path.size == 0)
return result;
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str16 path16 = DN_OS_W32Str8ToStr16(scratch.arena, path);
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
WIN32_FILE_ATTRIBUTE_DATA attrib_data = {};
if (!GetFileAttributesExW(path16.data, GetFileExInfoStandard, &attrib_data)) {
@@ -530,8 +530,8 @@ DN_API bool DN_OS_PathDelete(DN_Str8 path)
if (path.size == 0)
return result;
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str16 path16 = DN_OS_W32Str8ToStr16(scratch.arena, path);
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
if (path16.size) {
result = DeleteFileW(path16.data);
if (!result)
@@ -547,8 +547,8 @@ DN_API bool DN_OS_PathIsFile(DN_Str8 path)
if (path.size == 0)
return result;
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str16 path16 = DN_OS_W32Str8ToStr16(scratch.arena, path);
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
if (path16.size) {
WIN32_FILE_ATTRIBUTE_DATA attrib_data = {};
if (GetFileAttributesExW(path16.data, GetFileExInfoStandard, &attrib_data))
@@ -565,8 +565,8 @@ DN_API bool DN_OS_PathIsDir(DN_Str8 path)
if (path.size == 0)
return result;
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str16 path16 = DN_OS_W32Str8ToStr16(scratch.arena, path);
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
if (path16.size) {
WIN32_FILE_ATTRIBUTE_DATA attrib_data = {};
if (GetFileAttributesExW(path16.data, GetFileExInfoStandard, &attrib_data))
@@ -580,9 +580,9 @@ DN_API bool DN_OS_PathIsDir(DN_Str8 path)
DN_API bool DN_OS_PathMakeDir(DN_Str8 path)
{
bool result = true;
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str16 path16 = DN_OS_W32Str8ToStr16(scratch.arena, path);
bool result = true;
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&scratch.arena, path);
// NOTE: Go back from the end of the string to all the directories in the
// string, and try to create them. Since Win32 API cannot create
@@ -653,12 +653,12 @@ 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_PathF(&scratch.arena, "%.*s*", DN_Str8PrintFmt(path));
else
adjusted_path = DN_OS_PathF(scratch.arena, "%.*s/*", DN_Str8PrintFmt(path));
adjusted_path = DN_OS_PathF(&scratch.arena, "%.*s/*", DN_Str8PrintFmt(path));
}
path16 = DN_OS_W32Str8ToStr16(scratch.arena, adjusted_path);
path16 = DN_OS_W32Str8ToStr16(&scratch.arena, adjusted_path);
if (path16.size <= 0) { // Conversion error
DN_TCScratchEnd(&scratch);
return false;
@@ -676,8 +676,6 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it)
return result;
}
// NOTE: DN_OSExec /////////////////////////////////////////////////////////////////////////////////
DN_API void DN_OS_Exit(int32_t exit_code)
{
ExitProcess(DN_Cast(UINT) exit_code);
@@ -729,7 +727,7 @@ DN_API DN_OSExecResult DN_OS_ExecPump(DN_OSExecAsyncHandle handle,
exec_result = WaitForSingleObject(handle.process, timeout_ms);
if (exec_result == WAIT_FAILED) {
DN_OSW32Error win_error = DN_OS_W32LastError(scratch.arena);
DN_OSW32Error win_error = DN_OS_W32LastError(&scratch.arena);
result.os_error_code = win_error.code;
DN_ErrSinkAppendF(err, result.os_error_code, "Executed command failed to terminate: %.*s", DN_Str8PrintFmt(win_error.msg));
DN_TCScratchEnd(&scratch);
@@ -779,7 +777,7 @@ DN_API DN_OSExecResult DN_OS_ExecPump(DN_OSExecAsyncHandle handle,
if (GetExitCodeProcess(handle.process, &exit_status)) {
result.exit_code = exit_status;
} else {
DN_OSW32Error win_error = DN_OS_W32LastError(scratch.arena);
DN_OSW32Error win_error = DN_OS_W32LastError(&scratch.arena);
result.os_error_code = win_error.code;
DN_ErrSinkAppendF(err,
result.os_error_code,
@@ -824,12 +822,12 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle, DN_Arena *are
return result;
}
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
DN_Str8Builder stdout_builder = {};
DN_Str8Builder stderr_builder = {};
if (arena) {
stdout_builder.arena = scratch.arena;
stderr_builder.arena = scratch.arena;
stdout_builder = DN_Str8BuilderFromArena(&scratch.arena);
stderr_builder = DN_Str8BuilderFromArena(&scratch.arena);
}
DN_U32 const SLOW_WAIT_TIME_MS = 100;
@@ -838,15 +836,15 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle, DN_Arena *are
while (!result.finished) {
size_t stdout_size = DN_Kilobytes(8);
size_t stderr_size = DN_Kilobytes(8);
char *stdout_buffer = DN_ArenaNewArray(scratch.arena, char, stdout_size, DN_ZMem_No);
char *stderr_buffer = DN_ArenaNewArray(scratch.arena, char, stderr_size, DN_ZMem_No);
char *stdout_buffer = DN_ArenaNewArray(&scratch.arena, char, stdout_size, DN_ZMem_No);
char *stderr_buffer = DN_ArenaNewArray(&scratch.arena, char, stderr_size, DN_ZMem_No);
result = DN_OS_ExecPump(handle, stdout_buffer, &stdout_size, stderr_buffer, &stderr_size, wait_ms, err);
DN_Str8BuilderAppendCopy(&stdout_builder, result.stdout_text);
DN_Str8BuilderAppendCopy(&stderr_builder, result.stderr_text);
wait_ms = (result.stdout_text.size || result.stderr_text.size) ? FAST_WAIT_TIME_MS : SLOW_WAIT_TIME_MS;
}
// NOTE: Get stdout/stderr. If no arena is passed this is a no-op //////////////////////////////
// NOTE: Get stdout/stderr. If no arena is passed this is a no-op
result.stdout_text = DN_Str8BuilderBuild(&stdout_builder, arena);
result.stderr_text = DN_Str8BuilderBuild(&stderr_builder, arena);
DN_TCScratchEnd(&scratch);
@@ -861,19 +859,19 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line, DN_OSExecArgs
return result;
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
DN_Str8 cmd_rendered = DN_Str8SliceRender(cmd_line, DN_Str8Lit(" "), scratch.arena);
DN_Str16 cmd16 = DN_OS_W32Str8ToStr16(scratch.arena, cmd_rendered);
DN_Str16 working_dir16 = DN_OS_W32Str8ToStr16(scratch.arena, args->working_dir);
DN_Str8 cmd_rendered = DN_Str8SliceRender(cmd_line, DN_Str8Lit(" "), &scratch.arena);
DN_Str16 cmd16 = DN_OS_W32Str8ToStr16(&scratch.arena, cmd_rendered);
DN_Str16 working_dir16 = DN_OS_W32Str8ToStr16(&scratch.arena, args->working_dir);
DN_Str8Builder env_builder = DN_Str8BuilderFromArena(scratch.arena);
DN_Str8Builder env_builder = DN_Str8BuilderFromArena(&scratch.arena);
DN_Str8BuilderAppendArrayRef(&env_builder, args->environment.data, args->environment.count);
if (env_builder.string_size)
DN_Str8BuilderAppendRef(&env_builder, DN_Str8Lit("\0"));
DN_Str8 env_block8 = DN_Str8BuilderBuildDelimited(&env_builder, DN_Str8Lit("\0"), scratch.arena);
DN_Str8 env_block8 = DN_Str8BuilderBuildDelimited(&env_builder, DN_Str8Lit("\0"), &scratch.arena);
DN_Str16 env_block16 = {};
if (env_block8.size)
env_block16 = DN_OS_W32Str8ToStr16(scratch.arena, env_block8);
env_block16 = DN_OS_W32Str8ToStr16(&scratch.arena, env_block8);
// NOTE: Stdout/err security attributes
SECURITY_ATTRIBUTES save_std_security_attribs = {};
@@ -893,7 +891,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line, DN_OSExecArgs
if (DN_BitIsSet(args->flags, DN_OSExecFlags_SaveStdout)) {
if (!CreatePipe(&stdout_read, &stdout_write, &save_std_security_attribs, /*nSize*/ 0)) {
DN_OSW32Error win_error = DN_OS_W32LastError(scratch.arena);
DN_OSW32Error win_error = DN_OS_W32LastError(&scratch.arena);
result.os_error_code = win_error.code;
DN_ErrSinkAppendF(
err,
@@ -906,7 +904,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line, DN_OSExecArgs
}
if (!SetHandleInformation(stdout_read, HANDLE_FLAG_INHERIT, 0)) {
DN_OSW32Error win_error = DN_OS_W32LastError(scratch.arena);
DN_OSW32Error win_error = DN_OS_W32LastError(&scratch.arena);
result.os_error_code = win_error.code;
DN_ErrSinkAppendF(err,
result.os_error_code,
@@ -936,7 +934,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line, DN_OSExecArgs
stderr_write = stdout_write;
} else {
if (!CreatePipe(&stderr_read, &stderr_write, &save_std_security_attribs, /*nSize*/ 0)) {
DN_OSW32Error win_error = DN_OS_W32LastError(scratch.arena);
DN_OSW32Error win_error = DN_OS_W32LastError(&scratch.arena);
result.os_error_code = win_error.code;
DN_ErrSinkAppendF(
err,
@@ -949,7 +947,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line, DN_OSExecArgs
}
if (!SetHandleInformation(stderr_read, HANDLE_FLAG_INHERIT, 0)) {
DN_OSW32Error win_error = DN_OS_W32LastError(scratch.arena);
DN_OSW32Error win_error = DN_OS_W32LastError(&scratch.arena);
result.os_error_code = win_error.code;
DN_ErrSinkAppendF(err,
result.os_error_code,
@@ -963,7 +961,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line, DN_OSExecArgs
}
}
// NOTE: Execute command ///////////////////////////////////////////////////////////////////////
// NOTE: Execute command
PROCESS_INFORMATION proc_info = {};
STARTUPINFOW startup_info = {};
startup_info.cb = sizeof(STARTUPINFOW);
@@ -982,14 +980,14 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Str8Slice cmd_line, DN_OSExecArgs
&startup_info,
&proc_info);
if (!create_result) {
DN_OSW32Error win_error = DN_OS_W32LastError(scratch.arena);
DN_OSW32Error win_error = DN_OS_W32LastError(&scratch.arena);
result.os_error_code = win_error.code;
DN_ErrSinkAppendF(err, result.os_error_code, "Failed to execute command '%.*s': %.*s", DN_Str8PrintFmt(cmd_rendered), DN_Str8PrintFmt(win_error.msg));
DN_TCScratchEnd(&scratch);
return result;
}
// NOTE: Post-amble ////////////////////////////////////////////////////////////////////////////
// NOTE: Post-amble
CloseHandle(proc_info.hThread);
result.process = proc_info.hProcess;
result.stdout_read = stdout_read;
@@ -1280,7 +1278,7 @@ DN_API bool DN_OS_ThreadInit(DN_OSThread *thread, DN_OSThreadFunc *func, DN_OSTh
return result;
}
DN_API bool DN_OS_ThreadJoin(DN_OSThread *thread)
DN_API bool DN_OS_ThreadJoin(DN_OSThread *thread, DN_TCDeinitArenas deinit_arenas)
{
bool result = false;
if (thread && thread->handle) {
@@ -1289,7 +1287,7 @@ DN_API bool DN_OS_ThreadJoin(DN_OSThread *thread)
CloseHandle(thread->handle);
thread->handle = INVALID_HANDLE_VALUE;
thread->thread_id = {};
DN_TCDeinit(&thread->context);
DN_TCDeinit(&thread->context, deinit_arenas);
}
return result;
}
@@ -1309,7 +1307,7 @@ DN_API void DN_OS_W32ThreadSetName(DN_Str8 name)
DN_OSW32Core *w32 = DN_OS_W32GetCore();
DN_TCScratch scratch = DN_TCScratchBegin(nullptr, 0);
if (w32->set_thread_description) {
DN_Str16 name16 = DN_OS_W32Str8ToStr16(scratch.arena, name);
DN_Str16 name16 = DN_OS_W32Str8ToStr16(&scratch.arena, name);
w32->set_thread_description(GetCurrentThread(), (WCHAR *)name16.data);
} else {
// NOTE: Fallback to throw-exception method to set thread name
@@ -1323,11 +1321,11 @@ DN_API void DN_OS_W32ThreadSetName(DN_Str8 name)
};
#pragma pack(pop)
DN_Str8 copy = DN_Str8FromStr8Arena(scratch.arena, name);
DN_Str8 copy = DN_Str8FromStr8Arena(name, &scratch.arena);
DN_OSW32ThreadNameInfo info = {};
info.dwType = 0x1000;
info.szName = (char *)copy.data;
info.dwThreadID = DN_OS_ThreadID();
info.dwType = 0x1000;
info.szName = (char *)copy.data;
info.dwThreadID = DN_OS_ThreadID();
// TODO: Review warning 6320
DN_MSVC_WARNING_PUSH
@@ -1342,7 +1340,6 @@ DN_API void DN_OS_W32ThreadSetName(DN_Str8 name)
DN_TCScratchEnd(&scratch);
}
// NOTE: DN_OSHttp /////////////////////////////////////////////////////////////////////////////////
void DN_OS_HttpRequestWin32Callback(HINTERNET session, DWORD *dwContext, DWORD dwInternetStatus, VOID *lpvStatusInformation, DWORD dwStatusInformationLength)
{
(void)session;
@@ -1449,13 +1446,12 @@ DN_API void DN_OS_HttpRequestAsync(DN_OSHttpResponse *response,
if (!response || !arena)
return;
response->arena = arena;
response->builder.arena = response->scratch_arena ? response->scratch_arena : &response->tmp_arena;
response->arena = arena;
response->builder = DN_Str8BuilderFromArena(response->scratch_arena.mem ? &response->scratch_arena : &response->tmp_arena);
DN_Arena *scratch_arena = response->scratch_arena;
DN_TCScratch scratch_ = DN_TCScratchBegin(&arena, 1);
if (!scratch_arena)
scratch_arena = scratch_.arena;
DN_TCScratch scratch_ = DN_TCScratchBegin(&arena, 1);
if (!response->scratch_arena.mem)
response->scratch_arena = scratch_.arena;
DN_OSW32Error error = {};
DN_DEFER
@@ -1489,28 +1485,28 @@ DN_API void DN_OS_HttpRequestAsync(DN_OSHttpResponse *response,
return;
}
DN_Str16 host16 = DN_OS_W32Str8ToStr16(scratch_arena, host);
DN_Str16 host16 = DN_OS_W32Str8ToStr16(&response->scratch_arena, host);
response->w32_request_connection = WinHttpConnect(response->w32_request_session, host16.data, secure ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT, 0 /*reserved*/);
if (!response->w32_request_connection) {
error = DN_OS_W32LastError(&response->tmp_arena);
return;
}
DN_Str16 method16 = DN_OS_W32Str8ToStr16(scratch_arena, method);
DN_Str16 path16 = DN_OS_W32Str8ToStr16(scratch_arena, path);
DN_Str16 method16 = DN_OS_W32Str8ToStr16(&response->scratch_arena, method);
DN_Str16 path16 = DN_OS_W32Str8ToStr16(&response->scratch_arena, path);
response->w32_request_handle = WinHttpOpenRequest(response->w32_request_connection,
method16.data,
path16.data,
nullptr /*version*/,
nullptr /*referrer*/,
nullptr /*accept types*/,
secure ? WINHTTP_FLAG_SECURE : 0);
method16.data,
path16.data,
nullptr /*version*/,
nullptr /*referrer*/,
nullptr /*accept types*/,
secure ? WINHTTP_FLAG_SECURE : 0);
if (!response->w32_request_handle) {
error = DN_OS_W32LastError(&response->tmp_arena);
return;
}
DN_Str16 headers16 = DN_OS_W32Str8ToStr16(scratch_arena, headers);
DN_Str16 headers16 = DN_OS_W32Str8ToStr16(&response->scratch_arena, headers);
response->on_complete_semaphore = DN_OS_SemaphoreInit(0);
if (!WinHttpSendRequest(response->w32_request_handle,
headers16.data,
@@ -1535,7 +1531,7 @@ DN_API void DN_OS_HttpRequestFree(DN_OSHttpResponse *response)
response->w32_request_session = nullptr;
response->w32_request_connection = nullptr;
response->w32_request_handle = nullptr;
DN_ArenaDeinit(&response->tmp_arena);
DN_MemListDeinit(response->tmp_arena.mem);
DN_OS_SemaphoreDeinit(&response->on_complete_semaphore);
*response = {};
@@ -1626,7 +1622,6 @@ DN_API void DN_OS_W32MakeProcessDPIAware()
set_process_dpi_aware();
}
// NOTE: Windows UTF8 to Str16 //////////////////////////////////////////////
DN_API DN_Str16 DN_OS_W32Str8ToStr16(DN_Arena *arena, DN_Str8 src)
{
DN_Str16 result = {};
@@ -1665,7 +1660,6 @@ DN_API int DN_OS_W32Str8ToStr16Buffer(DN_Str8 src, wchar_t *dest, int dest_size)
return result;
}
// NOTE: Windows Str16 To UTF8 //////////////////////////////////////////////////////////////////
DN_API int DN_OS_W32Str16ToStr8Buffer(DN_Str16 src, char *dest, int dest_size)
{
int result = 0;
@@ -1701,18 +1695,16 @@ DN_API DN_Str8 DN_OS_W32Str16ToStr8(DN_Arena *arena, DN_Str16 src)
// NOTE: Str8 allocate ensures there's one extra byte for
// null-termination already so no-need to +1 the required size
DN_ArenaTempMemScope temp_mem = DN_ArenaTempMemScope(arena);
DN_Str8 buffer = DN_Str8AllocArena(arena, required_size, DN_ZMem_No);
if (buffer.size == 0)
return result;
int chars_written = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, src.data, src_size, buffer.data, DN_Cast(int) buffer.size, nullptr, nullptr);
if (DN_Check(chars_written == required_size)) {
result = buffer;
result.data[result.size] = 0;
temp_mem.mem = {};
DN_Arena temp = DN_ArenaTempBeginFromArena(arena);
DN_Str8 buffer = DN_Str8AllocArena(required_size, DN_ZMem_No, &temp);
if (buffer.size) {
int chars_written = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, src.data, src_size, buffer.data, DN_Cast(int) buffer.size, nullptr, nullptr);
if (DN_Check(chars_written == required_size)) {
result = buffer;
result.data[result.size] = 0;
}
}
DN_ArenaTempEnd(&temp, result.size == DN_Cast(DN_USize)required_size ? DN_ArenaReset_No : DN_ArenaReset_Yes);
return result;
}
@@ -1757,7 +1749,7 @@ DN_API DN_Str16 DN_OS_W32EXEPathW(DN_Arena *arena)
wchar_t *module_path = nullptr;
do {
module_size += 256;
module_path = DN_ArenaNewArray(scratch.arena, wchar_t, module_size, DN_ZMem_No);
module_path = DN_ArenaNewArray(&scratch.arena, wchar_t, module_size, DN_ZMem_No);
if (!module_path) {
DN_TCScratchEnd(&scratch);
return result;
@@ -1786,7 +1778,7 @@ DN_API DN_Str16 DN_OS_W32EXEDirW(DN_Arena *arena)
wchar_t *module_path = nullptr;
do {
module_size += 256;
module_path = DN_ArenaNewArray(scratch.arena, wchar_t, module_size, DN_ZMem_No);
module_path = DN_ArenaNewArray(&scratch.arena, wchar_t, module_size, DN_ZMem_No);
if (!module_path) {
DN_TCScratchEnd(&scratch);
return result;
@@ -1808,10 +1800,10 @@ DN_API DN_Str16 DN_OS_W32EXEDirW(DN_Arena *arena)
DN_API DN_Str8 DN_OS_W32WorkingDir(DN_Arena *arena, DN_Str8 suffix)
{
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
DN_Str16 suffix16 = DN_OS_W32Str8ToStr16(scratch.arena, suffix);
DN_Str16 dir16 = DN_OS_W32WorkingDirW(scratch.arena, suffix16);
DN_Str8 result = DN_OS_W32Str16ToStr8(arena, dir16);
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
DN_Str16 suffix16 = DN_OS_W32Str8ToStr16(&scratch.arena, suffix);
DN_Str16 dir16 = DN_OS_W32WorkingDirW(&scratch.arena, suffix16);
DN_Str8 result = DN_OS_W32Str16ToStr8(arena, dir16);
DN_TCScratchEnd(&scratch);
return result;
}
@@ -1822,11 +1814,11 @@ DN_API DN_Str16 DN_OS_W32WorkingDirW(DN_Arena *arena, DN_Str16 suffix)
DN_Str16 result = {};
// NOTE: required_size is the size required *including* the null-terminator
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
DN_TCScratch scratch = DN_TCScratchBegin(&arena, 1);
unsigned long required_size = GetCurrentDirectoryW(0, nullptr);
unsigned long desired_size = required_size + DN_Cast(unsigned long) suffix.size;
wchar_t *scratch_w_path = DN_ArenaNewArray(scratch.arena, wchar_t, desired_size, DN_ZMem_No);
wchar_t *scratch_w_path = DN_ArenaNewArray(&scratch.arena, wchar_t, desired_size, DN_ZMem_No);
if (!scratch_w_path) {
DN_TCScratchEnd(&scratch);
return result;