More revising of the API from The Bar

This commit is contained in:
2025-09-07 18:46:37 +10:00
parent 338be96138
commit 5c150c08dc
17 changed files with 1676 additions and 1290 deletions
+76 -40
View File
@@ -1,5 +1,8 @@
#define DN_OS_CPP
#include "../dn_base_inc.h"
#include "../dn_os_inc.h"
#if defined(DN_PLATFORM_POSIX)
#include <sys/sysinfo.h> // get_nprocs
#include <unistd.h> // getpagesize
@@ -389,11 +392,9 @@ DN_API uint64_t DN_OS_EstimateTSCPerSecond(uint64_t duration_ms_to_gauge_tsc_fre
return result;
}
#if !defined(DN_NO_OS_FILE_API)
// NOTE: DN_OSPathInfo/File ////////////////////////////////////////////////////////////////////////
DN_API bool DN_OS_FileIsOlderThan(DN_Str8 file, DN_Str8 check_against)
DN_API bool DN_OS_PathIsOlderThan(DN_Str8 path, DN_Str8 check_against)
{
DN_OSPathInfo file_info = DN_OS_PathInfo(file);
DN_OSPathInfo file_info = DN_OS_PathInfo(path);
DN_OSPathInfo check_against_info = DN_OS_PathInfo(check_against);
bool result = !file_info.exists || file_info.last_write_time_in_s < check_against_info.last_write_time_in_s;
return result;
@@ -445,44 +446,69 @@ DN_API bool DN_OS_FileWriteF(DN_OSFile *file, DN_OSErrSink *error, DN_FMT_ATTRIB
return result;
}
// NOTE: R/W Entire File ///////////////////////////////////////////////////////////////////////////
DN_API DN_Str8 DN_OS_ReadAll(DN_Arena *arena, DN_Str8 path, DN_OSErrSink *error)
DN_API DN_Str8 DN_OS_FileReadAll(DN_Allocator alloc_type, void *allocator, DN_Str8 path, DN_OSErrSink *err)
{
DN_Str8 result = {};
if (!arena)
return result;
// NOTE: Query file size + allocate buffer /////////////////////////////////////////////////////
// NOTE: Query file size
DN_Str8 result = {};
DN_OSPathInfo path_info = DN_OS_PathInfo(path);
if (!path_info.exists) {
DN_OS_ErrSinkAppendF(error, 1, "File does not exist/could not be queried for reading '%.*s'", DN_STR_FMT(path));
DN_OS_ErrSinkAppendF(err, 1, "File does not exist/could not be queried for reading '%.*s'", DN_STR_FMT(path));
return result;
}
DN_ArenaTempMem temp_mem = DN_Arena_TempMemBegin(arena);
result = DN_Str8_Alloc(arena, path_info.size, DN_ZeroMem_No);
if (!DN_Str8_HasData(result)) {
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str8 buffer_size_str8 = DN_CVT_BytesStr8FromU64AutoTLS(path_info.size);
DN_OS_ErrSinkAppendF(error, 1 /*error_code*/, "Failed to allocate %.*s for reading file '%.*s'", DN_STR_FMT(buffer_size_str8), DN_STR_FMT(path));
DN_Arena_TempMemEnd(temp_mem);
result = {};
// NOTE: Allocate
DN_ArenaTempMem arena_tmp = {};
if (alloc_type == DN_Allocator_Arena) {
DN_Arena *arena = DN_CAST(DN_Arena *) allocator;
arena_tmp = DN_Arena_TempMemBegin(arena);
result = DN_Str8_Alloc(arena, path_info.size, DN_ZeroMem_No);
} else {
DN_Pool *pool = DN_CAST(DN_Pool *) allocator;
result = DN_Str8_AllocPool(pool, path_info.size);
}
if (!result.data) {
DN_CVTU64Bytes bytes_str = DN_CVT_BytesFromU64Auto(path_info.size);
DN_OS_ErrSinkAppendF(err, 1 /*err_code*/, "Failed to allocate %.1f %.*s for reading file '%.*s'", bytes_str.bytes, DN_STR_FMT(bytes_str.suffix), DN_STR_FMT(path));
return result;
}
// NOTE: Read the file from disk ///////////////////////////////////////////////////////////////
DN_OSFile file = DN_OS_FileOpen(path, DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_Read, error);
DN_OSFileRead read = DN_OS_FileRead(&file, result.data, result.size, error);
// 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) {
DN_Arena_TempMemEnd(temp_mem);
if (alloc_type == DN_Allocator_Arena) {
DN_Arena_TempMemEnd(arena_tmp);
} else {
DN_Pool *pool = DN_CAST(DN_Pool *) allocator;
DN_Pool_Dealloc(pool, result.data);
}
result = {};
}
DN_OS_FileClose(&file);
DN_OS_FileClose(&file);
return result;
}
DN_API bool DN_OS_WriteAll(DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *error)
DN_API DN_Str8 DN_OS_FileReadAllArena(DN_Arena *arena, DN_Str8 path, DN_OSErrSink *err)
{
DN_Str8 result = DN_OS_FileReadAll(DN_Allocator_Arena, arena, path, err);
return result;
}
DN_API DN_Str8 DN_OS_FileReadAllPool(DN_Pool *pool, DN_Str8 path, DN_OSErrSink *err)
{
DN_Str8 result = DN_OS_FileReadAll(DN_Allocator_Pool, pool, path, err);
return result;
}
DN_API DN_Str8 DN_OS_FileReadAllTLS(DN_Str8 path, DN_OSErrSink *err)
{
DN_Str8 result = DN_OS_FileReadAll(DN_Allocator_Arena, DN_OS_TLSArena(), path, err);
return result;
}
DN_API bool DN_OS_FileWriteAll(DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *error)
{
DN_OSFile file = DN_OS_FileOpen(path, DN_OSFileOpen_CreateAlways, DN_OSFileAccess_Write, error);
bool result = DN_OS_FileWrite(&file, buffer, error);
@@ -490,54 +516,52 @@ DN_API bool DN_OS_WriteAll(DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *error)
return result;
}
DN_API bool DN_OS_WriteAllFV(DN_Str8 file_path, DN_OSErrSink *error, DN_FMT_ATTRIB char const *fmt, va_list args)
DN_API bool DN_OS_FileWriteAllFV(DN_Str8 file_path, DN_OSErrSink *error, DN_FMT_ATTRIB char const *fmt, va_list args)
{
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str8 buffer = DN_Str8_FromFV(tmem.arena, fmt, args);
bool result = DN_OS_WriteAll(file_path, buffer, error);
DN_Str8 buffer = DN_Str8_FromFV(tmem.arena, fmt, args);
bool result = DN_OS_FileWriteAll(file_path, buffer, error);
return result;
}
DN_API bool DN_OS_WriteAllF(DN_Str8 file_path, DN_OSErrSink *error, DN_FMT_ATTRIB char const *fmt, ...)
DN_API bool DN_OS_FileWriteAllF(DN_Str8 file_path, DN_OSErrSink *error, DN_FMT_ATTRIB char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
bool result = DN_OS_WriteAllFV(file_path, error, fmt, args);
bool result = DN_OS_FileWriteAllFV(file_path, error, fmt, args);
va_end(args);
return result;
}
DN_API bool DN_OS_WriteAllSafe(DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *error)
DN_API bool DN_OS_FileWriteAllSafe(DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *error)
{
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str8 tmp_path = DN_Str8_FromF(tmem.arena, "%.*s.tmp", DN_STR_FMT(path));
if (!DN_OS_WriteAll(tmp_path, buffer, error))
if (!DN_OS_FileWriteAll(tmp_path, buffer, error))
return false;
if (!DN_OS_CopyFile(tmp_path, path, true /*overwrite*/, error))
if (!DN_OS_FileCopy(tmp_path, path, true /*overwrite*/, error))
return false;
if (!DN_OS_PathDelete(tmp_path))
return false;
return true;
}
DN_API bool DN_OS_WriteAllSafeFV(DN_Str8 path, DN_OSErrSink *error, DN_FMT_ATTRIB char const *fmt, va_list args)
DN_API bool DN_OS_FileWriteAllSafeFV(DN_Str8 path, DN_OSErrSink *error, DN_FMT_ATTRIB char const *fmt, va_list args)
{
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str8 buffer = DN_Str8_FromFV(tmem.arena, fmt, args);
bool result = DN_OS_WriteAllSafe(path, buffer, error);
bool result = DN_OS_FileWriteAllSafe(path, buffer, error);
return result;
}
DN_API bool DN_OS_WriteAllSafeF(DN_Str8 path, DN_OSErrSink *error, DN_FMT_ATTRIB char const *fmt, ...)
DN_API bool DN_OS_FileWriteAllSafeF(DN_Str8 path, DN_OSErrSink *error, DN_FMT_ATTRIB char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
bool result = DN_OS_WriteAllSafeFV(path, error, fmt, args);
bool result = DN_OS_FileWriteAllSafeFV(path, error, fmt, args);
return result;
}
#endif // !defined(DN_NO_OS_FILE_API)
// NOTE: DN_OSPath /////////////////////////////////////////////////////////////////////////////////
DN_API bool DN_OS_PathAddRef(DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path)
{
if (!arena || !fs_path || !DN_Str8_HasData(path))
@@ -581,6 +605,18 @@ DN_API bool DN_OS_PathAddRef(DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path)
return true;
}
DN_API bool DN_OS_PathAddRefTLS(DN_OSPath *fs_path, DN_Str8 path)
{
bool result = DN_OS_PathAddRef(DN_OS_TLSTopArena(), fs_path, path);
return result;
}
DN_API bool DN_OS_PathAddRefFrame(DN_OSPath *fs_path, DN_Str8 path)
{
bool result = DN_OS_PathAddRef(DN_OS_TLSFrameArena(), fs_path, path);
return result;
}
DN_API bool DN_OS_PathAdd(DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path)
{
DN_Str8 copy = DN_Str8_FromStr8(arena, path);
+106 -111
View File
@@ -1,6 +1,9 @@
#if !defined(DN_OS_H)
#define DN_OS_H
#include "../dn_base_inc.h"
#include "../dn_os_inc.h"
#include <new> // operator new
#if !defined(DN_OS_WIN32) || defined(DN_OS_WIN32_USE_PTHREADS)
@@ -302,94 +305,87 @@ struct DN_OSDiskSpace
DN_U64 size;
};
DN_API void DN_OS_Init (DN_OSCore *os, DN_OSInitArgs *args);
DN_API void DN_OS_EmitLogsWithOSPrintFunctions(DN_OSCore *os);
DN_API void DN_OS_DumpThreadContextArenaStat (DN_Str8 file_path);
DN_API void DN_OS_Init (DN_OSCore *os, DN_OSInitArgs *args);
DN_API void DN_OS_EmitLogsWithOSPrintFunctions (DN_OSCore *os);
DN_API void DN_OS_DumpThreadContextArenaStat (DN_Str8 file_path);
// NOTE: Memory ////////////////////////////////////////////////////////////////////////////////////
DN_API void * DN_OS_MemReserve (DN_USize size, DN_MemCommit commit, DN_MemPage page_flags);
DN_API bool DN_OS_MemCommit (void *ptr, DN_USize size, DN_U32 page_flags);
DN_API void DN_OS_MemDecommit(void *ptr, DN_USize size);
DN_API void DN_OS_MemRelease (void *ptr, DN_USize size);
DN_API int DN_OS_MemProtect (void *ptr, DN_USize size, DN_U32 page_flags);
DN_API void * DN_OS_MemReserve (DN_USize size, DN_MemCommit commit, DN_MemPage page_flags);
DN_API bool DN_OS_MemCommit (void *ptr, DN_USize size, DN_U32 page_flags);
DN_API void DN_OS_MemDecommit (void *ptr, DN_USize size);
DN_API void DN_OS_MemRelease (void *ptr, DN_USize size);
DN_API int DN_OS_MemProtect (void *ptr, DN_USize size, DN_U32 page_flags);
// NOTE: Heap
DN_API void * DN_OS_MemAlloc (DN_USize size, DN_ZeroMem zero_mem);
DN_API void DN_OS_MemDealloc (void *ptr);
DN_API void * DN_OS_MemAlloc (DN_USize size, DN_ZeroMem zero_mem);
DN_API void DN_OS_MemDealloc (void *ptr);
// NOTE: DN_OSDate /////////////////////////////////////////////////////////////////////////////////
DN_API DN_OSDateTime DN_OS_DateLocalTimeNow ();
DN_API DN_OSDateTimeStr8 DN_OS_DateLocalTimeStr8Now(char date_separator = '-', char hms_separator = ':');
DN_API DN_OSDateTimeStr8 DN_OS_DateLocalTimeStr8 (DN_OSDateTime time, char date_separator = '-', char hms_separator = ':');
DN_API DN_U64 DN_OS_DateUnixTimeNs ();
#define DN_OS_DateUnixTimeUs() (DN_OS_DateUnixTimeNs() / 1000)
#define DN_OS_DateUnixTimeMs() (DN_OS_DateUnixTimeNs() / (1000 * 1000))
#define DN_OS_DateUnixTimeS() (DN_OS_DateUnixTimeNs() / (1000 * 1000 * 1000))
DN_API DN_OSDateTime DN_OS_DateUnixTimeSToDate (DN_U64 time);
DN_API DN_U64 DN_OS_DateLocalToUnixTimeS(DN_OSDateTime date);
DN_API DN_U64 DN_OS_DateToUnixTimeS (DN_OSDateTime date);
DN_API bool DN_OS_DateIsValid (DN_OSDateTime date);
DN_API DN_OSDateTime DN_OS_DateLocalTimeNow ();
DN_API DN_OSDateTimeStr8 DN_OS_DateLocalTimeStr8Now (char date_separator = '-', char hms_separator = ':');
DN_API DN_OSDateTimeStr8 DN_OS_DateLocalTimeStr8 (DN_OSDateTime time, char date_separator = '-', char hms_separator = ':');
DN_API DN_U64 DN_OS_DateUnixTimeNs ();
#define DN_OS_DateUnixTimeUs() (DN_OS_DateUnixTimeNs() / 1000)
#define DN_OS_DateUnixTimeMs() (DN_OS_DateUnixTimeNs() / (1000 * 1000))
#define DN_OS_DateUnixTimeS() (DN_OS_DateUnixTimeNs() / (1000 * 1000 * 1000))
DN_API DN_OSDateTime DN_OS_DateUnixTimeSToDate (DN_U64 time);
DN_API DN_U64 DN_OS_DateLocalToUnixTimeS (DN_OSDateTime date);
DN_API DN_U64 DN_OS_DateToUnixTimeS (DN_OSDateTime date);
DN_API bool DN_OS_DateIsValid (DN_OSDateTime date);
// NOTE: Other /////////////////////////////////////////////////////////////////////////////////////
DN_API void DN_OS_GenBytesSecure (void *buffer, DN_U32 size);
DN_API bool DN_OS_SetEnvVar (DN_Str8 name, DN_Str8 value);
DN_API DN_OSDiskSpace DN_OS_DiskSpace (DN_Str8 path);
DN_API DN_Str8 DN_OS_EXEPath (DN_Arena *arena);
DN_API DN_Str8 DN_OS_EXEDir (DN_Arena *arena);
#define DN_OS_EXEDirFromTLS() DN_OS_EXEDir(DN_OS_TLSTopArena())
DN_API void DN_OS_SleepMs (DN_UInt milliseconds);
DN_API void DN_OS_GenBytesSecure (void *buffer, DN_U32 size);
DN_API bool DN_OS_SetEnvVar (DN_Str8 name, DN_Str8 value);
DN_API DN_OSDiskSpace DN_OS_DiskSpace (DN_Str8 path);
DN_API DN_Str8 DN_OS_EXEPath (DN_Arena *arena);
DN_API DN_Str8 DN_OS_EXEDir (DN_Arena *arena);
#define DN_OS_EXEDirFromTLS() DN_OS_EXEDir(DN_OS_TLSTopArena())
DN_API void DN_OS_SleepMs (DN_UInt milliseconds);
// NOTE: Counters //////////////////////////////////////////////////////////////////////////////////
DN_API DN_U64 DN_OS_PerfCounterNow ();
DN_API DN_U64 DN_OS_PerfCounterFrequency();
DN_API DN_F64 DN_OS_PerfCounterS (DN_U64 begin, uint64_t end);
DN_API DN_F64 DN_OS_PerfCounterMs (DN_U64 begin, uint64_t end);
DN_API DN_F64 DN_OS_PerfCounterUs (DN_U64 begin, uint64_t end);
DN_API DN_F64 DN_OS_PerfCounterNs (DN_U64 begin, uint64_t end);
DN_API DN_OSTimer DN_OS_TimerBegin ();
DN_API void DN_OS_TimerEnd (DN_OSTimer *timer);
DN_API DN_F64 DN_OS_TimerS (DN_OSTimer timer);
DN_API DN_F64 DN_OS_TimerMs (DN_OSTimer timer);
DN_API DN_F64 DN_OS_TimerUs (DN_OSTimer timer);
DN_API DN_F64 DN_OS_TimerNs (DN_OSTimer timer);
DN_API DN_U64 DN_OS_EstimateTSCPerSecond(uint64_t duration_ms_to_gauge_tsc_frequency);
#if !defined(DN_NO_OS_FILE_API)
// NOTE: File system paths /////////////////////////////////////////////////////////////////////////
DN_API DN_OSPathInfo DN_OS_PathInfo (DN_Str8 path);
DN_API bool DN_OS_FileIsOlderThan(DN_Str8 file, DN_Str8 check_against);
DN_API bool DN_OS_PathDelete (DN_Str8 path);
DN_API bool DN_OS_FileExists (DN_Str8 path);
DN_API bool DN_OS_CopyFile (DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *err);
DN_API bool DN_OS_MoveFile (DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *err);
DN_API bool DN_OS_MakeDir (DN_Str8 path);
DN_API bool DN_OS_DirExists (DN_Str8 path);
DN_API bool DN_OS_DirIterate (DN_Str8 path, DN_OSDirIterator *it);
DN_API DN_U64 DN_OS_PerfCounterNow ();
DN_API DN_U64 DN_OS_PerfCounterFrequency ();
DN_API DN_F64 DN_OS_PerfCounterS (DN_U64 begin, uint64_t end);
DN_API DN_F64 DN_OS_PerfCounterMs (DN_U64 begin, uint64_t end);
DN_API DN_F64 DN_OS_PerfCounterUs (DN_U64 begin, uint64_t end);
DN_API DN_F64 DN_OS_PerfCounterNs (DN_U64 begin, uint64_t end);
DN_API DN_OSTimer DN_OS_TimerBegin ();
DN_API void DN_OS_TimerEnd (DN_OSTimer *timer);
DN_API DN_F64 DN_OS_TimerS (DN_OSTimer timer);
DN_API DN_F64 DN_OS_TimerMs (DN_OSTimer timer);
DN_API DN_F64 DN_OS_TimerUs (DN_OSTimer timer);
DN_API DN_F64 DN_OS_TimerNs (DN_OSTimer timer);
DN_API DN_U64 DN_OS_EstimateTSCPerSecond (uint64_t duration_ms_to_gauge_tsc_frequency);
// NOTE: R/W Stream API ////////////////////////////////////////////////////////////////////////////
DN_API DN_OSFile DN_OS_FileOpen (DN_Str8 path, DN_OSFileOpen open_mode, DN_OSFileAccess access, DN_OSErrSink *err);
DN_API DN_OSFileRead DN_OS_FileRead (DN_OSFile *file, void *buffer, DN_USize size, DN_OSErrSink *err);
DN_API bool DN_OS_FileWritePtr(DN_OSFile *file, void const *data, DN_USize size, DN_OSErrSink *err);
DN_API bool DN_OS_FileWrite (DN_OSFile *file, DN_Str8 buffer, DN_OSErrSink *err);
DN_API bool DN_OS_FileWriteFV (DN_OSFile *file, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, va_list args);
DN_API bool DN_OS_FileWriteF (DN_OSFile *file, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, ...);
DN_API bool DN_OS_FileFlush (DN_OSFile *file, DN_OSErrSink *err);
DN_API void DN_OS_FileClose (DN_OSFile *file);
DN_API bool DN_OS_FileCopy (DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *err);
DN_API bool DN_OS_FileMove (DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *err);
// NOTE: R/W Entire File ///////////////////////////////////////////////////////////////////////////
DN_API DN_Str8 DN_OS_ReadAll (DN_Arena *arena, DN_Str8 path, DN_OSErrSink *err);
#define DN_OS_ReadAllFromTLS(...) DN_OS_ReadAll(DN_OS_TLSTopArena(), ##__VA_ARGS__)
DN_API bool DN_OS_WriteAll (DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *err);
DN_API bool DN_OS_WriteAllFV (DN_Str8 path, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, va_list args);
DN_API bool DN_OS_WriteAllF (DN_Str8 path, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, ...);
DN_API bool DN_OS_WriteAllSafe (DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *err);
DN_API bool DN_OS_WriteAllSafeFV (DN_Str8 path, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, va_list args);
DN_API bool DN_OS_WriteAllSafeF (DN_Str8 path, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, ...);
#endif // !defined(DN_NO_OS_FILE_API)
DN_API DN_OSFile DN_OS_FileOpen (DN_Str8 path, DN_OSFileOpen open_mode, DN_OSFileAccess access, DN_OSErrSink *err);
DN_API DN_OSFileRead DN_OS_FileRead (DN_OSFile *file, void *buffer, DN_USize size, DN_OSErrSink *err);
DN_API bool DN_OS_FileWritePtr (DN_OSFile *file, void const *data, DN_USize size, DN_OSErrSink *err);
DN_API bool DN_OS_FileWrite (DN_OSFile *file, DN_Str8 buffer, DN_OSErrSink *err);
DN_API bool DN_OS_FileWriteFV (DN_OSFile *file, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, va_list args);
DN_API bool DN_OS_FileWriteF (DN_OSFile *file, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, ...);
DN_API bool DN_OS_FileFlush (DN_OSFile *file, DN_OSErrSink *err);
DN_API void DN_OS_FileClose (DN_OSFile *file);
DN_API DN_Str8 DN_OS_FileReadAll (DN_Allocator alloc_type, void *allocator, DN_Str8 path, DN_OSErrSink *err);
DN_API DN_Str8 DN_OS_FileReadAllArena (DN_Arena *arena, DN_Str8 path, DN_OSErrSink *err);
DN_API DN_Str8 DN_OS_FileReadAllPool (DN_Pool *pool, DN_Str8 path, DN_OSErrSink *err);
DN_API DN_Str8 DN_OS_FileReadAllTLS (DN_Str8 path, DN_OSErrSink *err);
DN_API bool DN_OS_FileWriteAll (DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *err);
DN_API bool DN_OS_FileWriteAllFV (DN_Str8 path, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, va_list args);
DN_API bool DN_OS_FileWriteAllF (DN_Str8 path, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, ...);
DN_API bool DN_OS_FileWriteAllSafe (DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *err);
DN_API bool DN_OS_FileWriteAllSafeFV (DN_Str8 path, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, va_list args);
DN_API bool DN_OS_FileWriteAllSafeF (DN_Str8 path, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, ...);
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);
DN_API bool DN_OS_PathIsFile (DN_Str8 path);
DN_API bool DN_OS_PathIsDir (DN_Str8 path);
DN_API bool DN_OS_PathMakeDir (DN_Str8 path);
DN_API bool DN_OS_PathIterateDir (DN_Str8 path, DN_OSDirIterator *it);
// NOTE: File system paths /////////////////////////////////////////////////////////////////////////
DN_API bool DN_OS_PathAddRef (DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path);
#define DN_OS_PathAddRefFromTLS(...) DN_OS_PathAddRef(DN_OS_TLSTopArena(), ##__VA_ARGS__)
#define DN_OS_PathAddRefFromFrame(...) DN_OS_PathAddRef(DN_OS_TLSFrameArena(), ##__VA_ARGS__)
DN_API bool DN_OS_PathAddRefTLS (DN_OSPath *fs_path, DN_Str8 path);
DN_API bool DN_OS_PathAddRefFrame (DN_OSPath *fs_path, DN_Str8 path);
DN_API bool DN_OS_PathAdd (DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path);
#define DN_OS_PathAddFromTLS(...) DN_OS_PathAdd(DN_OS_TLSTopArena(), ##__VA_ARGS__)
#define DN_OS_PathAddFromFrame(...) DN_OS_PathAdd(DN_OS_TLSFrameArena(), ##__VA_ARGS__)
@@ -417,41 +413,40 @@ DN_API DN_Str8 DN_OS_PathF (D
#define DN_OS_PathBuildBackSlash(allocator, fs_path) DN_OS_PathBuildWithSeparator(allocator, fs_path, DN_STR8("\\"))
#define DN_OS_PathBuild(allocator, fs_path) DN_OS_PathBuildWithSeparator(allocator, fs_path, DN_OSPathSeparatorString)
// NOTE: DN_OSExec /////////////////////////////////////////////////////////////////////////////////
DN_API void DN_OS_Exit (int32_t exit_code);
DN_API DN_OSExecResult DN_OS_ExecPump (DN_OSExecAsyncHandle handle, char *stdout_buffer, size_t *stdout_size, char *stderr_buffer, size_t *stderr_size, DN_U32 timeout_ms, DN_OSErrSink *err);
DN_API DN_OSExecResult DN_OS_ExecWait (DN_OSExecAsyncHandle handle, DN_Arena *arena, DN_OSErrSink *err);
DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync (DN_Slice<DN_Str8> cmd_line, DN_OSExecArgs *args, DN_OSErrSink *err);
DN_API DN_OSExecResult DN_OS_Exec (DN_Slice<DN_Str8> cmd_line, DN_OSExecArgs *args, DN_Arena *arena, DN_OSErrSink *err);
DN_API DN_OSExecResult DN_OS_ExecOrAbort (DN_Slice<DN_Str8> cmd_line, DN_OSExecArgs *args, DN_Arena *arena);
#define DN_OS_ExecOrAbortFromTLS(...) DN_OS_ExecOrAbort(__VA_ARGS__, DN_OS_TLSTopArena())
DN_API void DN_OS_Exit (int32_t exit_code);
DN_API DN_OSExecResult DN_OS_ExecPump (DN_OSExecAsyncHandle handle, char *stdout_buffer, size_t *stdout_size, char *stderr_buffer, size_t *stderr_size, DN_U32 timeout_ms, DN_OSErrSink *err);
DN_API DN_OSExecResult DN_OS_ExecWait (DN_OSExecAsyncHandle handle, DN_Arena *arena, DN_OSErrSink *err);
DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync (DN_Slice<DN_Str8> cmd_line, DN_OSExecArgs *args, DN_OSErrSink *err);
DN_API DN_OSExecResult DN_OS_Exec (DN_Slice<DN_Str8> cmd_line, DN_OSExecArgs *args, DN_Arena *arena, DN_OSErrSink *err);
DN_API DN_OSExecResult DN_OS_ExecOrAbort (DN_Slice<DN_Str8> cmd_line, DN_OSExecArgs *args, DN_Arena *arena);
#define DN_OS_ExecOrAbortFromTLS (...) DN_OS_ExecOrAbort(__VA_ARGS__, DN_OS_TLSTopArena())
DN_API DN_OSSemaphore DN_OS_SemaphoreInit (DN_U32 initial_count);
DN_API bool DN_OS_SemaphoreIsValid (DN_OSSemaphore *semaphore);
DN_API void DN_OS_SemaphoreDeinit (DN_OSSemaphore *semaphore);
DN_API void DN_OS_SemaphoreIncrement(DN_OSSemaphore *semaphore, DN_U32 amount);
DN_API DN_OSSemaphoreWaitResult DN_OS_SemaphoreWait (DN_OSSemaphore *semaphore, DN_U32 timeout_ms);
DN_API DN_OSSemaphore DN_OS_SemaphoreInit (DN_U32 initial_count);
DN_API bool DN_OS_SemaphoreIsValid (DN_OSSemaphore *semaphore);
DN_API void DN_OS_SemaphoreDeinit (DN_OSSemaphore *semaphore);
DN_API void DN_OS_SemaphoreIncrement (DN_OSSemaphore *semaphore, DN_U32 amount);
DN_API DN_OSSemaphoreWaitResult DN_OS_SemaphoreWait (DN_OSSemaphore *semaphore, DN_U32 timeout_ms);
DN_API DN_OSMutex DN_OS_MutexInit ();
DN_API void DN_OS_MutexDeinit(DN_OSMutex *mutex);
DN_API void DN_OS_MutexLock (DN_OSMutex *mutex);
DN_API void DN_OS_MutexUnlock(DN_OSMutex *mutex);
#define DN_OS_MutexScope(mutex) DN_DeferLoop(DN_OS_MutexLock(mutex), DN_OS_MutexUnlock(mutex))
DN_API DN_OSMutex DN_OS_MutexInit ();
DN_API void DN_OS_MutexDeinit (DN_OSMutex *mutex);
DN_API void DN_OS_MutexLock (DN_OSMutex *mutex);
DN_API void DN_OS_MutexUnlock (DN_OSMutex *mutex);
#define DN_OS_MutexScope (mutex) DN_DeferLoop(DN_OS_MutexLock(mutex), DN_OS_MutexUnlock(mutex))
DN_API DN_OSConditionVariable DN_OS_ConditionVariableInit ();
DN_API void DN_OS_ConditionVariableDeinit (DN_OSConditionVariable *cv);
DN_API bool DN_OS_ConditionVariableWait (DN_OSConditionVariable *cv, DN_OSMutex *mutex, DN_U64 sleep_ms);
DN_API bool DN_OS_ConditionVariableWaitUntil(DN_OSConditionVariable *cv, DN_OSMutex *mutex, DN_U64 end_ts_ms);
DN_API void DN_OS_ConditionVariableSignal (DN_OSConditionVariable *cv);
DN_API void DN_OS_ConditionVariableBroadcast(DN_OSConditionVariable *cv);
DN_API DN_OSConditionVariable DN_OS_ConditionVariableInit ();
DN_API void DN_OS_ConditionVariableDeinit (DN_OSConditionVariable *cv);
DN_API bool DN_OS_ConditionVariableWait (DN_OSConditionVariable *cv, DN_OSMutex *mutex, DN_U64 sleep_ms);
DN_API bool DN_OS_ConditionVariableWaitUntil (DN_OSConditionVariable *cv, DN_OSMutex *mutex, DN_U64 end_ts_ms);
DN_API void DN_OS_ConditionVariableSignal (DN_OSConditionVariable *cv);
DN_API void DN_OS_ConditionVariableBroadcast (DN_OSConditionVariable *cv);
DN_API bool DN_OS_ThreadInit (DN_OSThread *thread, DN_OSThreadFunc *func, void *user_context);
DN_API void DN_OS_ThreadDeinit(DN_OSThread *thread);
DN_API DN_U32 DN_OS_ThreadID ();
DN_API void DN_OS_ThreadSetName(DN_Str8 name);
DN_API bool DN_OS_ThreadInit (DN_OSThread *thread, DN_OSThreadFunc *func, void *user_context);
DN_API void DN_OS_ThreadDeinit (DN_OSThread *thread);
DN_API DN_U32 DN_OS_ThreadID ();
DN_API void DN_OS_ThreadSetName (DN_Str8 name);
DN_API void DN_OS_HttpRequestAsync(DN_OSHttpResponse *response, DN_Arena *arena, DN_Str8 host, DN_Str8 path, DN_OSHttpRequestSecure secure, DN_Str8 method, DN_Str8 body, DN_Str8 headers);
DN_API void DN_OS_HttpRequestWait (DN_OSHttpResponse *response);
DN_API void DN_OS_HttpRequestFree (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);
DN_API void DN_OS_HttpRequestAsync (DN_OSHttpResponse *response, DN_Arena *arena, DN_Str8 host, DN_Str8 path, DN_OSHttpRequestSecure secure, DN_Str8 method, DN_Str8 body, DN_Str8 headers);
DN_API void DN_OS_HttpRequestWait (DN_OSHttpResponse *response);
DN_API void DN_OS_HttpRequestFree (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);
#endif // !defined(DN_OS_H)
+1 -1
View File
@@ -1,7 +1,7 @@
#if !defined(DN_OS_ALLOCATOR_H)
#define DN_OS_ALLOCATOR_H
DN_API DN_Arena DN_Arena_FromOSHeap(DN_U64 size, DN_ArenaFlags flags);
DN_API DN_Arena DN_Arena_FromHeap(DN_U64 size, DN_ArenaFlags flags);
DN_API DN_Arena DN_Arena_FromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags);
#endif // !defined(DN_OS_ALLOCATOR_H)
+153 -157
View File
@@ -196,7 +196,7 @@ DN_API DN_OSDiskSpace DN_OS_DiskSpace(DN_Str8 path)
{
DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr);
DN_OSDiskSpace result = {};
DN_Str8 path_z_terminated = DN_Str8_Copy(tmem.arena, path);
DN_Str8 path_z_terminated = DN_Str8_FromStr8(tmem.arena, path);
struct statvfs info = {};
if (statvfs(path_z_terminated.data, &info) != 0)
@@ -297,52 +297,7 @@ DN_API DN_U64 DN_OS_PerfCounterNow()
return result;
}
#if !defined(DN_NO_OS_FILE_API)
DN_API DN_OSPathInfo DN_OS_PathInfo(DN_Str8 path)
{
DN_OSPathInfo result = {};
if (!DN_Str8_HasData(path))
return result;
struct stat file_stat;
if (lstat(path.data, &file_stat) != -1) {
result.exists = true;
result.size = file_stat.st_size;
result.last_access_time_in_s = file_stat.st_atime;
result.last_write_time_in_s = file_stat.st_mtime;
// TODO(dn): Seems linux does not support creation time via stat. We
// shoddily deal with this.
result.create_time_in_s = DN_Min(result.last_access_time_in_s, result.last_write_time_in_s);
if (S_ISDIR(file_stat.st_mode))
result.type = DN_OSPathInfoType_Directory;
else if (S_ISREG(file_stat.st_mode))
result.type = DN_OSPathInfoType_File;
}
return result;
}
DN_API bool DN_OS_PathDelete(DN_Str8 path)
{
bool result = false;
if (DN_Str8_HasData(path))
result = remove(path.data) == 0;
return result;
}
DN_API bool DN_OS_FileExists(DN_Str8 path)
{
bool result = false;
if (!DN_Str8_HasData(path))
return result;
struct stat stat_result;
if (lstat(path.data, &stat_result) != -1)
result = S_ISREG(stat_result.st_mode) || S_ISLNK(stat_result.st_mode);
return result;
}
DN_API bool DN_OS_CopyFile(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *error)
DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *error)
{
bool result = false;
#if defined(DN_PLATFORM_EMSCRIPTEN)
@@ -417,7 +372,7 @@ DN_API bool DN_OS_CopyFile(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi
return result;
}
DN_API bool DN_OS_MoveFile(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *error)
DN_API bool DN_OS_FileMove(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *error)
{
// See: https://github.com/gingerBill/gb/blob/master/gb.h
bool result = false;
@@ -425,7 +380,7 @@ DN_API bool DN_OS_MoveFile(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi
if (link(src.data, dest.data) == -1) {
// NOTE: Link can fail if we're trying to link across different volumes
// so we fall back to a binary directory.
file_moved |= DN_OS_CopyFile(src, dest, overwrite, error);
file_moved |= DN_OS_FileCopy(src, dest, overwrite, error);
}
if (file_moved) {
@@ -445,108 +400,6 @@ DN_API bool DN_OS_MoveFile(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi
return result;
}
DN_API bool DN_OS_MakeDir(DN_Str8 path)
{
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
bool result = true;
// TODO(doyle): Implement this without using the path indexes, it's not
// necessary. See Windows implementation.
DN_USize path_indexes_size = 0;
uint16_t path_indexes[64] = {};
DN_Str8 copy = DN_Str8_Copy(tmem.arena, path);
for (DN_USize index = copy.size - 1; index < copy.size; index--) {
bool first_char = index == (copy.size - 1);
char ch = copy.data[index];
if (ch == '/' || first_char) {
char temp = copy.data[index];
if (!first_char)
copy.data[index] = 0; // Temporarily null terminate it
bool is_file = DN_OS_FileExists(copy);
if (!first_char)
copy.data[index] = temp; // Undo null termination
if (is_file) {
// NOTE: There's something that exists in at this path, but
// it's not a directory. This request to make a directory is
// invalid.
return false;
} else if (DN_OS_DirExists(copy)) {
// NOTE: We found a directory, we can stop here and start
// building up all the directories that didn't exist up to
// this point.
break;
} else {
// NOTE: There's nothing that exists at this path, we can
// create a directory here
path_indexes[path_indexes_size++] = DN_CAST(uint16_t) index;
}
}
}
for (DN_USize index = path_indexes_size - 1; result && index < path_indexes_size; index--) {
uint16_t path_index = path_indexes[index];
char temp = copy.data[path_index];
if (index != 0)
copy.data[path_index] = 0;
result |= mkdir(copy.data, 0774) == 0;
if (index != 0)
copy.data[path_index] = temp;
}
return result;
}
DN_API bool DN_OS_DirExists(DN_Str8 path)
{
bool result = false;
if (!DN_Str8_HasData(path))
return result;
struct stat stat_result;
if (lstat(path.data, &stat_result) != -1)
result = S_ISDIR(stat_result.st_mode);
return result;
}
DN_API bool DN_OS_DirIterate(DN_Str8 path, DN_OSDirIterator *it)
{
if (!it->handle) {
it->handle = opendir(path.data);
if (!it->handle)
return false;
}
struct dirent *entry;
for (;;) {
entry = readdir(DN_CAST(DIR *) it->handle);
if (entry == NULL)
break;
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
DN_USize name_size = DN_CStr8_Size(entry->d_name);
DN_USize clamped_size = DN_Min(sizeof(it->buffer) - 1, name_size);
DN_AssertF(name_size == clamped_size, "name: %s, name_size: %zu, clamped_size: %zu", entry->d_name, name_size, clamped_size);
DN_Memcpy(it->buffer, entry->d_name, clamped_size);
it->buffer[clamped_size] = 0;
it->file_name = DN_Str8_Init(it->buffer, clamped_size);
return true;
}
closedir(DN_CAST(DIR *) it->handle);
it->handle = NULL;
it->file_name = {};
it->buffer[0] = 0;
return false;
}
// NOTE: R/W Stream API ////////////////////////////////////////////////////////////////////////////
DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path,
DN_OSFileOpen open_mode,
DN_OSFileAccess access,
@@ -678,9 +531,152 @@ DN_API void DN_OS_FileClose(DN_OSFile *file)
fclose(DN_CAST(FILE *) file->handle);
*file = {};
}
#endif // !defined(DN_NO_OS_FILE_API)
// NOTE: DN_OSExec /////////////////////////////////////////////////////////////////////////////////
DN_API DN_OSPathInfo DN_OS_PathInfo(DN_Str8 path)
{
DN_OSPathInfo result = {};
if (!DN_Str8_HasData(path))
return result;
struct stat file_stat;
if (lstat(path.data, &file_stat) != -1) {
result.exists = true;
result.size = file_stat.st_size;
result.last_access_time_in_s = file_stat.st_atime;
result.last_write_time_in_s = file_stat.st_mtime;
// TODO(dn): Seems linux does not support creation time via stat. We
// shoddily deal with this.
result.create_time_in_s = DN_Min(result.last_access_time_in_s, result.last_write_time_in_s);
if (S_ISDIR(file_stat.st_mode))
result.type = DN_OSPathInfoType_Directory;
else if (S_ISREG(file_stat.st_mode))
result.type = DN_OSPathInfoType_File;
}
return result;
}
DN_API bool DN_OS_PathDelete(DN_Str8 path)
{
bool result = false;
if (DN_Str8_HasData(path))
result = remove(path.data) == 0;
return result;
}
DN_API bool DN_OS_PathIsFile(DN_Str8 path)
{
bool result = false;
if (!DN_Str8_HasData(path))
return result;
struct stat stat_result;
if (lstat(path.data, &stat_result) != -1)
result = S_ISREG(stat_result.st_mode) || S_ISLNK(stat_result.st_mode);
return result;
}
DN_API bool DN_OS_PathIsDir(DN_Str8 path)
{
bool result = false;
if (!DN_Str8_HasData(path))
return result;
struct stat stat_result;
if (lstat(path.data, &stat_result) != -1)
result = S_ISDIR(stat_result.st_mode);
return result;
}
DN_API bool DN_OS_PathMakeDir(DN_Str8 path)
{
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
bool result = true;
// TODO(doyle): Implement this without using the path indexes, it's not
// necessary. See Windows implementation.
DN_USize path_indexes_size = 0;
uint16_t path_indexes[64] = {};
DN_Str8 copy = DN_Str8_FromStr8(tmem.arena, path);
for (DN_USize index = copy.size - 1; index < copy.size; index--) {
bool first_char = index == (copy.size - 1);
char ch = copy.data[index];
if (ch == '/' || first_char) {
char temp = copy.data[index];
if (!first_char)
copy.data[index] = 0; // Temporarily null terminate it
bool is_file = DN_OS_PathIsFile(copy);
if (!first_char)
copy.data[index] = temp; // Undo null termination
if (is_file) {
// NOTE: There's something that exists in at this path, but
// it's not a directory. This request to make a directory is
// invalid.
return false;
} else if (DN_OS_PathIsDir(copy)) {
// NOTE: We found a directory, we can stop here and start
// building up all the directories that didn't exist up to
// this point.
break;
} else {
// NOTE: There's nothing that exists at this path, we can
// create a directory here
path_indexes[path_indexes_size++] = DN_CAST(uint16_t) index;
}
}
}
for (DN_USize index = path_indexes_size - 1; result && index < path_indexes_size; index--) {
uint16_t path_index = path_indexes[index];
char temp = copy.data[path_index];
if (index != 0)
copy.data[path_index] = 0;
result |= mkdir(copy.data, 0774) == 0;
if (index != 0)
copy.data[path_index] = temp;
}
return result;
}
DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it)
{
if (!it->handle) {
it->handle = opendir(path.data);
if (!it->handle)
return false;
}
struct dirent *entry;
for (;;) {
entry = readdir(DN_CAST(DIR *) it->handle);
if (entry == NULL)
break;
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
DN_USize name_size = DN_CStr8_Size(entry->d_name);
DN_USize clamped_size = DN_Min(sizeof(it->buffer) - 1, name_size);
DN_AssertF(name_size == clamped_size, "name: %s, name_size: %zu, clamped_size: %zu", entry->d_name, name_size, clamped_size);
DN_Memcpy(it->buffer, entry->d_name, clamped_size);
it->buffer[clamped_size] = 0;
it->file_name = DN_Str8_Init(it->buffer, clamped_size);
return true;
}
closedir(DN_CAST(DIR *) it->handle);
it->handle = NULL;
it->file_name = {};
it->buffer[0] = 0;
return false;
}
DN_API void DN_OS_Exit(int32_t exit_code)
{
exit(DN_CAST(int) exit_code);
@@ -914,7 +910,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice<DN_Str8> cmd_line,
for (DN_ForIndexU(arg_index, cmd_line.size)) {
DN_Str8 arg = cmd_line.data[arg_index];
argv[arg_index] = DN_Str8_Copy(tmem.arena, arg).data; // NOTE: Copy string to guarantee it is null-terminated
argv[arg_index] = DN_Str8_FromStr8(tmem.arena, arg).data; // NOTE: Copy string to guarantee it is null-terminated
}
// NOTE: Change the working directory if there is one
@@ -932,7 +928,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice<DN_Str8> cmd_line,
if (args->working_dir.size) {
prev_working_dir = get_current_dir_name();
DN_Str8 working_dir = DN_Str8_Copy(tmem.arena, args->working_dir);
DN_Str8 working_dir = DN_Str8_FromStr8(tmem.arena, args->working_dir);
if (chdir(working_dir.data) == -1) {
result.os_error_code = errno;
DN_OS_ErrSinkAppendF(
@@ -1298,7 +1294,7 @@ DN_API void DN_Posix_ThreadSetName(DN_Str8 name)
(void)name;
#else
DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr);
DN_Str8 copy = DN_Str8_Copy(tmem.arena, name);
DN_Str8 copy = DN_Str8_FromStr8(tmem.arena, name);
pthread_t thread = pthread_self();
pthread_setname_np(thread, (char *)copy.data);
#endif
@@ -1322,7 +1318,7 @@ DN_API DN_POSIXProcSelfStatus DN_Posix_ProcSelfStatus()
if (!file.error) {
char buf[256];
DN_Str8Builder builder = DN_Str8Builder_InitFromTLS();
DN_Str8Builder builder = DN_Str8Builder_FromTLS();
for (;;) {
DN_OSFileRead read = DN_OS_FileRead(&file, buf, sizeof(buf), nullptr);
if (!read.success || read.bytes_read == 0)
+25 -24
View File
@@ -1,6 +1,9 @@
#if !defined(DN_OS_TLS_H)
#define DN_OS_TLS_H
#include "../dn_base_inc.h"
#include "../dn_os_inc.h"
// NOTE: DN_OSErrSink /////////////////////////////////////////////////////////////////////////////
enum DN_OSErrSinkMode
{
@@ -87,7 +90,6 @@ struct DN_OSTLSInitArgs
DN_U64 err_sink_commit;
};
// NOTE: DN_OSTLS ////////////////////////////////////////////////////////////////////////////////////
DN_API void DN_OS_TLSInit (DN_OSTLS *tls, DN_OSTLSInitArgs args);
DN_API void DN_OS_TLSDeinit (DN_OSTLS *tls);
DN_API DN_OSTLS * DN_OS_TLSGet ();
@@ -99,30 +101,29 @@ DN_API void DN_OS_TLSPopArena ();
DN_API DN_Arena * DN_OS_TLSTopArena ();
DN_API void DN_OS_TLSBeginFrame (DN_Arena *frame_arena);
DN_API DN_Arena * DN_OS_TLSFrameArena ();
#define DN_OS_TLSSaveCallSite do { DN_OS_TLSGet()->call_site = DN_CALL_SITE; } while (0)
#define DN_OS_TLSTMem(...) DN_OS_TLSGetTMem(__VA_ARGS__, DN_OSTLSPushTMem_No)
#define DN_OS_TLSPushTMem(...) DN_OS_TLSGetTMem(__VA_ARGS__, DN_OSTLSPushTMem_Yes)
#define DN_OS_TLSSaveCallSite do { DN_OS_TLSGet()->call_site = DN_CALL_SITE; } while (0)
#define DN_OS_TLSTMem(...) DN_OS_TLSGetTMem(__VA_ARGS__, DN_OSTLSPushTMem_No)
#define DN_OS_TLSPushTMem(...) DN_OS_TLSGetTMem(__VA_ARGS__, DN_OSTLSPushTMem_Yes)
// NOTE: DN_OS_ErrSink ////////////////////////////////////////////////////////////////////////////
DN_API DN_OSErrSink * DN_OS_ErrSinkBegin_ (DN_OSErrSinkMode mode, DN_CallSite call_site);
#define DN_OS_ErrSinkBegin(mode) DN_OS_ErrSinkBegin_(mode, DN_CALL_SITE)
#define DN_OS_ErrSinkBeginDefault() DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil)
DN_API bool DN_OS_ErrSinkHasError (DN_OSErrSink *err);
DN_API DN_OSErrSinkMsg *DN_OS_ErrSinkEnd (DN_Arena *arena, DN_OSErrSink *err);
DN_API DN_Str8 DN_OS_ErrSinkEndStr8 (DN_Arena *arena, DN_OSErrSink *err);
DN_API void DN_OS_ErrSinkEndAndIgnore (DN_OSErrSink *err);
DN_API bool DN_OS_ErrSinkEndAndLogError_ (DN_OSErrSink *err, DN_CallSite call_site, DN_Str8 msg);
DN_API bool DN_OS_ErrSinkEndAndLogErrorFV_ (DN_OSErrSink *err, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, va_list args);
DN_API bool DN_OS_ErrSinkEndAndLogErrorF_ (DN_OSErrSink *err, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, ...);
DN_API void DN_OS_ErrSinkEndAndExitIfErrorF_ (DN_OSErrSink *err, DN_CallSite call_site, DN_U32 exit_val, DN_FMT_ATTRIB char const *fmt, ...);
DN_API void DN_OS_ErrSinkEndAndExitIfErrorFV_ (DN_OSErrSink *err, DN_CallSite call_site, DN_U32 exit_val, DN_FMT_ATTRIB char const *fmt, va_list args);
DN_API void DN_OS_ErrSinkAppendFV_ (DN_OSErrSink *err, DN_U32 error_code, DN_FMT_ATTRIB char const *fmt, va_list args);
DN_API void DN_OS_ErrSinkAppendF_ (DN_OSErrSink *err, DN_U32 error_code, DN_FMT_ATTRIB char const *fmt, ...);
#define DN_OS_ErrSinkEndAndLogError(err, err_msg) DN_OS_ErrSinkEndAndLogError_(err, DN_CALL_SITE, err_msg)
#define DN_OS_ErrSinkEndAndLogErrorFV(err, fmt, args) DN_OS_ErrSinkEndAndLogErrorFV_(err, DN_CALL_SITE, fmt, args)
#define DN_OS_ErrSinkEndAndLogErrorF(err, fmt, ...) DN_OS_ErrSinkEndAndLogErrorF_(err, DN_CALL_SITE, fmt, ##__VA_ARGS__)
#define DN_OS_ErrSinkEndAndExitIfErrorFV(err, exit_val, fmt, args) DN_OS_ErrSinkEndAndExitIfErrorFV_(err, DN_CALL_SITE, exit_val, fmt, args)
#define DN_OS_ErrSinkEndAndExitIfErrorF(err, exit_val, fmt, ...) DN_OS_ErrSinkEndAndExitIfErrorF_(err, DN_CALL_SITE, exit_val, fmt, ##__VA_ARGS__)
DN_API DN_OSErrSink * DN_OS_ErrSinkBegin_ (DN_OSErrSinkMode mode, DN_CallSite call_site);
#define DN_OS_ErrSinkBegin(mode) DN_OS_ErrSinkBegin_(mode, DN_CALL_SITE)
#define DN_OS_ErrSinkBeginDefault() DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil)
DN_API bool DN_OS_ErrSinkHasError (DN_OSErrSink *err);
DN_API DN_OSErrSinkMsg * DN_OS_ErrSinkEnd (DN_Arena *arena, DN_OSErrSink *err);
DN_API DN_Str8 DN_OS_ErrSinkEndStr8 (DN_Arena *arena, DN_OSErrSink *err);
DN_API void DN_OS_ErrSinkEndAndIgnore (DN_OSErrSink *err);
DN_API bool DN_OS_ErrSinkEndAndLogError_ (DN_OSErrSink *err, DN_CallSite call_site, DN_Str8 msg);
DN_API bool DN_OS_ErrSinkEndAndLogErrorFV_ (DN_OSErrSink *err, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, va_list args);
DN_API bool DN_OS_ErrSinkEndAndLogErrorF_ (DN_OSErrSink *err, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, ...);
DN_API void DN_OS_ErrSinkEndAndExitIfErrorF_ (DN_OSErrSink *err, DN_CallSite call_site, DN_U32 exit_val, DN_FMT_ATTRIB char const *fmt, ...);
DN_API void DN_OS_ErrSinkEndAndExitIfErrorFV_ (DN_OSErrSink *err, DN_CallSite call_site, DN_U32 exit_val, DN_FMT_ATTRIB char const *fmt, va_list args);
DN_API void DN_OS_ErrSinkAppendFV_ (DN_OSErrSink *err, DN_U32 error_code, DN_FMT_ATTRIB char const *fmt, va_list args);
DN_API void DN_OS_ErrSinkAppendF_ (DN_OSErrSink *err, DN_U32 error_code, DN_FMT_ATTRIB char const *fmt, ...);
#define DN_OS_ErrSinkEndAndLogError(err, err_msg) DN_OS_ErrSinkEndAndLogError_(err, DN_CALL_SITE, err_msg)
#define DN_OS_ErrSinkEndAndLogErrorFV(err, fmt, args) DN_OS_ErrSinkEndAndLogErrorFV_(err, DN_CALL_SITE, fmt, args)
#define DN_OS_ErrSinkEndAndLogErrorF(err, fmt, ...) DN_OS_ErrSinkEndAndLogErrorF_(err, DN_CALL_SITE, fmt, ##__VA_ARGS__)
#define DN_OS_ErrSinkEndAndExitIfErrorFV(err, exit_val, fmt, args) DN_OS_ErrSinkEndAndExitIfErrorFV_(err, DN_CALL_SITE, exit_val, fmt, args)
#define DN_OS_ErrSinkEndAndExitIfErrorF(err, exit_val, fmt, ...) DN_OS_ErrSinkEndAndExitIfErrorF_(err, DN_CALL_SITE, exit_val, fmt, ##__VA_ARGS__)
#define DN_OS_ErrSinkAppendFV(error, error_code, fmt, args) \
do { \
+189 -191
View File
@@ -298,7 +298,6 @@ DN_API DN_U64 DN_OS_PerfCounterNow()
return result;
}
#if !defined(DN_NO_OS_FILE_API)
static DN_U64 DN_W32_FileTimeToSeconds_(FILETIME const *time)
{
ULARGE_INTEGER time_large_int = {};
@@ -308,73 +307,7 @@ static DN_U64 DN_W32_FileTimeToSeconds_(FILETIME const *time)
return result;
}
DN_API DN_OSPathInfo DN_OS_PathInfo(DN_Str8 path)
{
DN_OSPathInfo result = {};
if (!DN_Str8_HasData(path))
return result;
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str16 path16 = DN_W32_Str8ToStr16(tmem.arena, path);
WIN32_FILE_ATTRIBUTE_DATA attrib_data = {};
if (!GetFileAttributesExW(path16.data, GetFileExInfoStandard, &attrib_data))
return result;
result.exists = true;
result.create_time_in_s = DN_W32_FileTimeToSeconds_(&attrib_data.ftCreationTime);
result.last_access_time_in_s = DN_W32_FileTimeToSeconds_(&attrib_data.ftLastAccessTime);
result.last_write_time_in_s = DN_W32_FileTimeToSeconds_(&attrib_data.ftLastWriteTime);
LARGE_INTEGER large_int = {};
large_int.u.HighPart = DN_CAST(int32_t) attrib_data.nFileSizeHigh;
large_int.u.LowPart = attrib_data.nFileSizeLow;
result.size = (DN_U64)large_int.QuadPart;
if (attrib_data.dwFileAttributes != INVALID_FILE_ATTRIBUTES) {
if (attrib_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
result.type = DN_OSPathInfoType_Directory;
else
result.type = DN_OSPathInfoType_File;
}
return result;
}
DN_API bool DN_OS_PathDelete(DN_Str8 path)
{
bool result = false;
if (!DN_Str8_HasData(path))
return result;
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str16 path16 = DN_W32_Str8ToStr16(tmem.arena, path);
if (path16.size) {
result = DeleteFileW(path16.data);
if (!result)
result = RemoveDirectoryW(path16.data);
}
return result;
}
DN_API bool DN_OS_FileExists(DN_Str8 path)
{
bool result = false;
if (!DN_Str8_HasData(path))
return result;
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str16 path16 = DN_W32_Str8ToStr16(tmem.arena, path);
if (path16.size) {
WIN32_FILE_ATTRIBUTE_DATA attrib_data = {};
if (GetFileAttributesExW(path16.data, GetFileExInfoStandard, &attrib_data))
result = (attrib_data.dwFileAttributes != INVALID_FILE_ATTRIBUTES) &&
!(attrib_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
}
return result;
}
DN_API bool DN_OS_CopyFile(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *err)
DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *err)
{
bool result = false;
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
@@ -397,12 +330,12 @@ DN_API bool DN_OS_CopyFile(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi
return result;
}
DN_API bool DN_OS_MoveFile(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *err)
DN_API bool DN_OS_FileMove(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *err)
{
bool result = false;
bool result = false;
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str16 src16 = DN_W32_Str8ToStr16(tmem.arena, src);
DN_Str16 dest16 = DN_W32_Str8ToStr16(tmem.arena, dest);
DN_Str16 src16 = DN_W32_Str8ToStr16(tmem.arena, src);
DN_Str16 dest16 = DN_W32_Str8ToStr16(tmem.arena, dest);
unsigned long flags = MOVEFILE_COPY_ALLOWED;
if (overwrite)
@@ -412,128 +345,16 @@ DN_API bool DN_OS_MoveFile(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi
if (!result) {
DN_W32Error win_error = DN_W32_LastError(tmem.arena);
DN_OS_ErrSinkAppendF(err,
win_error.code,
"Failed to move file '%.*s' to '%.*s': (%u) %.*s",
DN_STR_FMT(src),
DN_STR_FMT(dest),
win_error.code,
DN_STR_FMT(win_error.msg));
win_error.code,
"Failed to move file '%.*s' to '%.*s': (%u) %.*s",
DN_STR_FMT(src),
DN_STR_FMT(dest),
win_error.code,
DN_STR_FMT(win_error.msg));
}
return result;
}
DN_API bool DN_OS_MakeDir(DN_Str8 path)
{
bool result = true;
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str16 path16 = DN_W32_Str8ToStr16(tmem.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
// intermediate directories that don't exist in a path we need to go back
// and record all the directories until we encounter one that exists.
//
// From that point onwards go forwards and make all the directories
// inbetween by null-terminating the string temporarily, creating the
// directory and so forth until we reach the end.
//
// If we find a file at some point in the path we fail out because the
// series of directories can not be made if a file exists with the same
// name.
for (DN_USize index = 0; index < path16.size; index++) {
bool first_char = index == (path16.size - 1);
wchar_t ch = path16.data[index];
if (ch == '/' || ch == '\\' || first_char) {
wchar_t temp = path16.data[index];
if (!first_char)
path16.data[index] = 0; // Temporarily null terminate it
WIN32_FILE_ATTRIBUTE_DATA attrib_data = {};
bool successful = GetFileAttributesExW(path16.data, GetFileExInfoStandard, &attrib_data); // Check
if (successful) {
if (attrib_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
// NOTE: The directory exists, continue iterating the path
} else {
// NOTE: There's some kind of file that exists at the path
// but it's not a directory. This request to make a
// directory is invalid.
return false;
}
} else {
// NOTE: There's nothing that exists at this path, we can create
// a directory here
result |= (CreateDirectoryW(path16.data, nullptr) == 0);
}
if (!first_char)
path16.data[index] = temp; // Undo null termination
}
}
return result;
}
DN_API bool DN_OS_DirExists(DN_Str8 path)
{
bool result = false;
if (!DN_Str8_HasData(path))
return result;
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str16 path16 = DN_W32_Str8ToStr16(tmem.arena, path);
if (path16.size) {
WIN32_FILE_ATTRIBUTE_DATA attrib_data = {};
if (GetFileAttributesExW(path16.data, GetFileExInfoStandard, &attrib_data))
result = (attrib_data.dwFileAttributes != INVALID_FILE_ATTRIBUTES) &&
(attrib_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
}
return result;
}
DN_API bool DN_OS_DirIterate(DN_Str8 path, DN_OSDirIterator *it)
{
if (!DN_Str8_HasData(path) || !it || path.size <= 0)
return false;
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_W32FolderIteratorW wide_it = {};
DN_Str16 path16 = {};
if (it->handle) {
wide_it.handle = it->handle;
} else {
bool needs_asterisks = DN_Str8_EndsWith(path, DN_STR8("\\")) ||
DN_Str8_EndsWith(path, DN_STR8("/"));
bool has_glob = DN_Str8_EndsWith(path, DN_STR8("\\*")) ||
DN_Str8_EndsWith(path, DN_STR8("/*"));
DN_Str8 adjusted_path = path;
if (!has_glob) {
// NOTE: We are missing the glob for enumerating the files, we will
// 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(tmem.arena, "%.*s*", DN_STR_FMT(path));
else
adjusted_path = DN_OS_PathF(tmem.arena, "%.*s/*", DN_STR_FMT(path));
}
path16 = DN_W32_Str8ToStr16(tmem.arena, adjusted_path);
if (path16.size <= 0) // Conversion error
return false;
}
bool result = DN_W32_DirWIterate(path16, &wide_it);
it->handle = wide_it.handle;
if (result) {
int size = DN_W32_Str16ToStr8Buffer(wide_it.file_name, it->buffer, DN_ArrayCountU(it->buffer));
it->file_name = DN_Str8_Init(it->buffer, size);
}
return result;
}
// NOTE: R/W Stream API ////////////////////////////////////////////////////////////////////////////
DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path, DN_OSFileOpen open_mode, DN_U32 access, DN_OSErrSink *err)
{
DN_OSFile result = {};
@@ -680,7 +501,184 @@ DN_API void DN_OS_FileClose(DN_OSFile *file)
CloseHandle(file->handle);
*file = {};
}
#endif // !defined(DN_NO_OS_FILE_API)
DN_API DN_OSPathInfo DN_OS_PathInfo(DN_Str8 path)
{
DN_OSPathInfo result = {};
if (!DN_Str8_HasData(path))
return result;
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str16 path16 = DN_W32_Str8ToStr16(tmem.arena, path);
WIN32_FILE_ATTRIBUTE_DATA attrib_data = {};
if (!GetFileAttributesExW(path16.data, GetFileExInfoStandard, &attrib_data))
return result;
result.exists = true;
result.create_time_in_s = DN_W32_FileTimeToSeconds_(&attrib_data.ftCreationTime);
result.last_access_time_in_s = DN_W32_FileTimeToSeconds_(&attrib_data.ftLastAccessTime);
result.last_write_time_in_s = DN_W32_FileTimeToSeconds_(&attrib_data.ftLastWriteTime);
LARGE_INTEGER large_int = {};
large_int.u.HighPart = DN_CAST(int32_t) attrib_data.nFileSizeHigh;
large_int.u.LowPart = attrib_data.nFileSizeLow;
result.size = (DN_U64)large_int.QuadPart;
if (attrib_data.dwFileAttributes != INVALID_FILE_ATTRIBUTES) {
if (attrib_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
result.type = DN_OSPathInfoType_Directory;
else
result.type = DN_OSPathInfoType_File;
}
return result;
}
DN_API bool DN_OS_PathDelete(DN_Str8 path)
{
bool result = false;
if (!DN_Str8_HasData(path))
return result;
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str16 path16 = DN_W32_Str8ToStr16(tmem.arena, path);
if (path16.size) {
result = DeleteFileW(path16.data);
if (!result)
result = RemoveDirectoryW(path16.data);
}
return result;
}
DN_API bool DN_OS_PathIsFile(DN_Str8 path)
{
bool result = false;
if (!DN_Str8_HasData(path))
return result;
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str16 path16 = DN_W32_Str8ToStr16(tmem.arena, path);
if (path16.size) {
WIN32_FILE_ATTRIBUTE_DATA attrib_data = {};
if (GetFileAttributesExW(path16.data, GetFileExInfoStandard, &attrib_data))
result = (attrib_data.dwFileAttributes != INVALID_FILE_ATTRIBUTES) &&
!(attrib_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
}
return result;
}
DN_API bool DN_OS_PathIsDir(DN_Str8 path)
{
bool result = false;
if (!DN_Str8_HasData(path))
return result;
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str16 path16 = DN_W32_Str8ToStr16(tmem.arena, path);
if (path16.size) {
WIN32_FILE_ATTRIBUTE_DATA attrib_data = {};
if (GetFileAttributesExW(path16.data, GetFileExInfoStandard, &attrib_data))
result = (attrib_data.dwFileAttributes != INVALID_FILE_ATTRIBUTES) &&
(attrib_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
}
return result;
}
DN_API bool DN_OS_PathMakeDir(DN_Str8 path)
{
bool result = true;
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str16 path16 = DN_W32_Str8ToStr16(tmem.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
// intermediate directories that don't exist in a path we need to go back
// and record all the directories until we encounter one that exists.
//
// From that point onwards go forwards and make all the directories
// inbetween by null-terminating the string temporarily, creating the
// directory and so forth until we reach the end.
//
// If we find a file at some point in the path we fail out because the
// series of directories can not be made if a file exists with the same
// name.
for (DN_USize index = 0; index < path16.size; index++) {
bool first_char = index == (path16.size - 1);
wchar_t ch = path16.data[index];
if (ch == '/' || ch == '\\' || first_char) {
wchar_t temp = path16.data[index];
if (!first_char)
path16.data[index] = 0; // Temporarily null terminate it
WIN32_FILE_ATTRIBUTE_DATA attrib_data = {};
bool successful = GetFileAttributesExW(path16.data, GetFileExInfoStandard, &attrib_data); // Check
if (successful) {
if (attrib_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
// NOTE: The directory exists, continue iterating the path
} else {
// NOTE: There's some kind of file that exists at the path
// but it's not a directory. This request to make a
// directory is invalid.
return false;
}
} else {
// NOTE: There's nothing that exists at this path, we can create
// a directory here
result |= (CreateDirectoryW(path16.data, nullptr) == 0);
}
if (!first_char)
path16.data[index] = temp; // Undo null termination
}
}
return result;
}
DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it)
{
if (!DN_Str8_HasData(path) || !it || path.size <= 0)
return false;
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_W32FolderIteratorW wide_it = {};
DN_Str16 path16 = {};
if (it->handle) {
wide_it.handle = it->handle;
} else {
bool needs_asterisks = DN_Str8_EndsWith(path, DN_STR8("\\")) ||
DN_Str8_EndsWith(path, DN_STR8("/"));
bool has_glob = DN_Str8_EndsWith(path, DN_STR8("\\*")) ||
DN_Str8_EndsWith(path, DN_STR8("/*"));
DN_Str8 adjusted_path = path;
if (!has_glob) {
// NOTE: We are missing the glob for enumerating the files, we will
// 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(tmem.arena, "%.*s*", DN_STR_FMT(path));
else
adjusted_path = DN_OS_PathF(tmem.arena, "%.*s/*", DN_STR_FMT(path));
}
path16 = DN_W32_Str8ToStr16(tmem.arena, adjusted_path);
if (path16.size <= 0) // Conversion error
return false;
}
bool result = DN_W32_DirWIterate(path16, &wide_it);
it->handle = wide_it.handle;
if (result) {
int size = DN_W32_Str16ToStr8Buffer(wide_it.file_name, it->buffer, DN_ArrayCountU(it->buffer));
it->file_name = DN_Str8_Init(it->buffer, size);
}
return result;
}
// NOTE: DN_OSExec /////////////////////////////////////////////////////////////////////////////////
DN_API void DN_OS_Exit(int32_t exit_code)