More revising of the API from The Bar

This commit is contained in:
doylet 2025-09-07 18:46:37 +10:00
parent 338be96138
commit 5c150c08dc
17 changed files with 1676 additions and 1290 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// Generated by the DN single header generator 2025-09-03 22:49:06 // Generated by the DN single header generator 2025-09-07 18:46:16
#if !defined(DN_BASE_INC_H) #if !defined(DN_BASE_INC_H)
#define DN_BASE_INC_H #define DN_BASE_INC_H
@ -166,9 +166,9 @@
#endif #endif
#if defined(__cplusplus) #if defined(__cplusplus)
#define DN_LITERAL(T) T #define DN_Literal(T) T
#else #else
#define DN_LITERAL(T) (T) #define DN_Literal(T) (T)
#endif #endif
// NOTE: Thread Locals ///////////////////////////////////////////////////////////////////////////// // NOTE: Thread Locals /////////////////////////////////////////////////////////////////////////////
@ -893,6 +893,12 @@ enum DN_MemPage_
#define DN_ARENA_COMMIT_SIZE DN_Kilobytes(64) #define DN_ARENA_COMMIT_SIZE DN_Kilobytes(64)
#endif #endif
enum DN_Allocator
{
DN_Allocator_Arena,
DN_Allocator_Pool,
};
struct DN_ArenaBlock struct DN_ArenaBlock
{ {
DN_ArenaBlock *prev; DN_ArenaBlock *prev;
@ -3213,16 +3219,17 @@ DN_API DN_Str8 DN_Str8_Alloc (DN_Arena *aren
DN_API DN_Str8 DN_Str8_FromCStr8 (char const *src); DN_API DN_Str8 DN_Str8_FromCStr8 (char const *src);
DN_API DN_Str8 DN_Str8_FromF (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...); DN_API DN_Str8 DN_Str8_FromF (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...);
DN_API DN_Str8 DN_Str8_FromFV (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8 DN_Str8_FromFV (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args);
DN_API DN_Str8 DN_Str8_FromFPool (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...);
DN_API DN_Str8 DN_Str8_FromStr8 (DN_Arena *arena, DN_Str8 string); DN_API DN_Str8 DN_Str8_FromStr8 (DN_Arena *arena, DN_Str8 string);
DN_API bool DN_Str8_IsAll (DN_Str8 string, DN_Str8IsAll is_all); DN_API bool DN_Str8_IsAll (DN_Str8 string, DN_Str8IsAll is_all);
DN_API char * DN_Str8_End (DN_Str8 string); DN_API char * DN_Str8_End (DN_Str8 string);
DN_API DN_Str8 DN_Str8_Slice (DN_Str8 string, DN_USize offset, DN_USize size); DN_API DN_Str8 DN_Str8_Slice (DN_Str8 string, DN_USize offset, DN_USize size);
DN_API DN_Str8 DN_Str8_Advance (DN_Str8 string, DN_USize amount); DN_API DN_Str8 DN_Str8_Advance (DN_Str8 string, DN_USize amount);
DN_API DN_Str8 DN_Str8_NextLine (DN_Str8 string); DN_API DN_Str8 DN_Str8_NextLine (DN_Str8 string);
DN_API DN_Str8BSplitResult DN_Str8_BSplitArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size); DN_API DN_Str8BSplitResult DN_Str8_BSplitArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size);
DN_API DN_Str8BSplitResult DN_Str8_BSplit (DN_Str8 string, DN_Str8 find); DN_API DN_Str8BSplitResult DN_Str8_BSplit (DN_Str8 string, DN_Str8 find);
DN_API DN_Str8BSplitResult DN_Str8_BSplitLastArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size); DN_API DN_Str8BSplitResult DN_Str8_BSplitLastArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size);
DN_API DN_Str8BSplitResult DN_Str8_BSplitLast (DN_Str8 string, DN_Str8 find); DN_API DN_Str8BSplitResult DN_Str8_BSplitLast (DN_Str8 string, DN_Str8 find);
DN_API DN_USize DN_Str8_Split (DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_USize splits_count, DN_Str8SplitIncludeEmptyStrings mode); DN_API DN_USize DN_Str8_Split (DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_USize splits_count, DN_Str8SplitIncludeEmptyStrings mode);
DN_API DN_Slice<DN_Str8> DN_Str8_SplitAlloc (DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode); DN_API DN_Slice<DN_Str8> DN_Str8_SplitAlloc (DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode);
DN_API DN_Str8FindResult DN_Str8_FindStr8Array (DN_Str8 string, DN_Str8 const *find, DN_USize find_size, DN_Str8EqCase eq_case); DN_API DN_Str8FindResult DN_Str8_FindStr8Array (DN_Str8 string, DN_Str8 const *find, DN_USize find_size, DN_Str8EqCase eq_case);
@ -3841,8 +3848,8 @@ DN_API DN_CVTU64Str8 DN_CVT_Str8FromU64 (DN_U6
DN_API DN_CVTU64Bytes DN_CVT_BytesFromU64 (DN_U64 bytes, DN_CVTBytesType type); DN_API DN_CVTU64Bytes DN_CVT_BytesFromU64 (DN_U64 bytes, DN_CVTBytesType type);
#define DN_CVT_BytesFromU64Auto(bytes) DN_CVT_BytesFromU64(bytes, DN_CVTBytesType_Auto) #define DN_CVT_BytesFromU64Auto(bytes) DN_CVT_BytesFromU64(bytes, DN_CVTBytesType_Auto)
DN_API DN_Str8 DN_CVT_BytesStr8FromU64 (DN_Arena *arena, DN_U64 bytes, DN_CVTBytesType type); DN_API DN_Str8 DN_CVT_BytesStr8FromU64 (DN_Arena *arena, DN_U64 bytes, DN_CVTBytesType type);
#define DN_CVT_BytesStr8FromU64Auto(arena, bytes) DN_CVT_BytesStr8FromU64(arena, bytes, DN_CVTBytesType_Auto)
#define DN_CVT_BytesStr8FromTLS(bytes, type) DN_CVT_BytesStr8FromU64(DN_OS_TLSTopArena(), bytes, type) #define DN_CVT_BytesStr8FromTLS(bytes, type) DN_CVT_BytesStr8FromU64(DN_OS_TLSTopArena(), bytes, type)
#define DN_CVT_BytesStr8FromU64Auto(arena, bytes) DN_CVT_BytesStr8FromU64(arena, bytes, DN_CVTBytesType_Auto)
#define DN_CVT_BytesStr8FromU64AutoTLS(bytes) DN_CVT_BytesStr8FromU64(DN_OS_TLSTopArena(), bytes, DN_CVTBytesType_Auto) #define DN_CVT_BytesStr8FromU64AutoTLS(bytes) DN_CVT_BytesStr8FromU64(DN_OS_TLSTopArena(), bytes, DN_CVTBytesType_Auto)
#define DN_CVT_BytesStr8FromU64Frame(bytes, type) DN_CVT_BytesStr8FromU64(DN_OS_TLSFrameArena(), bytes, type) #define DN_CVT_BytesStr8FromU64Frame(bytes, type) DN_CVT_BytesStr8FromU64(DN_OS_TLSFrameArena(), bytes, type)
#define DN_CVT_BytesStr8FromU64AutoFrame(bytes) DN_CVT_BytesStr8FromU64(DN_OS_TLSFrameArena(), bytes, DN_CVTBytesType_Auto) #define DN_CVT_BytesStr8FromU64AutoFrame(bytes) DN_CVT_BytesStr8FromU64(DN_OS_TLSFrameArena(), bytes, DN_CVTBytesType_Auto)
@ -5372,6 +5379,9 @@ DN_API DN_POSIXProcSelfStatus DN_Posix_ProcSelfStatus();
#if !defined(DN_OS_TLS_H) #if !defined(DN_OS_TLS_H)
#define DN_OS_TLS_H #define DN_OS_TLS_H
// DN: Single header generator commented out this header => #include "../dn_base_inc.h"
// DN: Single header generator commented out this header => #include "../dn_os_inc.h"
// NOTE: DN_OSErrSink ///////////////////////////////////////////////////////////////////////////// // NOTE: DN_OSErrSink /////////////////////////////////////////////////////////////////////////////
enum DN_OSErrSinkMode enum DN_OSErrSinkMode
{ {
@ -5458,7 +5468,6 @@ struct DN_OSTLSInitArgs
DN_U64 err_sink_commit; 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_TLSInit (DN_OSTLS *tls, DN_OSTLSInitArgs args);
DN_API void DN_OS_TLSDeinit (DN_OSTLS *tls); DN_API void DN_OS_TLSDeinit (DN_OSTLS *tls);
DN_API DN_OSTLS * DN_OS_TLSGet (); DN_API DN_OSTLS * DN_OS_TLSGet ();
@ -5470,30 +5479,29 @@ DN_API void DN_OS_TLSPopArena ();
DN_API DN_Arena * DN_OS_TLSTopArena (); DN_API DN_Arena * DN_OS_TLSTopArena ();
DN_API void DN_OS_TLSBeginFrame (DN_Arena *frame_arena); DN_API void DN_OS_TLSBeginFrame (DN_Arena *frame_arena);
DN_API DN_Arena * DN_OS_TLSFrameArena (); 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_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_TLSTMem(...) DN_OS_TLSGetTMem(__VA_ARGS__, DN_OSTLSPushTMem_No)
#define DN_OS_TLSPushTMem(...) DN_OS_TLSGetTMem(__VA_ARGS__, DN_OSTLSPushTMem_Yes) #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);
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_ErrSinkBegin(mode) DN_OS_ErrSinkBegin_(mode, DN_CALL_SITE) #define DN_OS_ErrSinkBeginDefault() DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil)
#define DN_OS_ErrSinkBeginDefault() DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil) DN_API bool DN_OS_ErrSinkHasError (DN_OSErrSink *err);
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_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 DN_Str8 DN_OS_ErrSinkEndStr8 (DN_Arena *arena, DN_OSErrSink *err); DN_API void DN_OS_ErrSinkEndAndIgnore (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_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_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 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_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_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_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, ...);
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_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_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_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_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_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) \ #define DN_OS_ErrSinkAppendFV(error, error_code, fmt, args) \
do { \ do { \
@ -5512,6 +5520,9 @@ DN_API void DN_OS_ErrSinkAppendF_ (DN_OSErrSink *err,
#if !defined(DN_OS_H) #if !defined(DN_OS_H)
#define DN_OS_H #define DN_OS_H
// DN: Single header generator commented out this header => #include "../dn_base_inc.h"
// DN: Single header generator commented out this header => #include "../dn_os_inc.h"
#include <new> // operator new #include <new> // operator new
#if !defined(DN_OS_WIN32) || defined(DN_OS_WIN32_USE_PTHREADS) #if !defined(DN_OS_WIN32) || defined(DN_OS_WIN32_USE_PTHREADS)
@ -5813,94 +5824,87 @@ struct DN_OSDiskSpace
DN_U64 size; DN_U64 size;
}; };
DN_API void DN_OS_Init (DN_OSCore *os, DN_OSInitArgs *args); 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_EmitLogsWithOSPrintFunctions (DN_OSCore *os);
DN_API void DN_OS_DumpThreadContextArenaStat (DN_Str8 file_path); 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 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 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_MemDecommit(void *ptr, DN_USize size); DN_API void DN_OS_MemRelease (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 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_MemAlloc (DN_USize size, DN_ZeroMem zero_mem); DN_API void DN_OS_MemDealloc (void *ptr);
DN_API void DN_OS_MemDealloc (void *ptr);
// NOTE: DN_OSDate ///////////////////////////////////////////////////////////////////////////////// DN_API DN_OSDateTime DN_OS_DateLocalTimeNow ();
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_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_OSDateTimeStr8 DN_OS_DateLocalTimeStr8 (DN_OSDateTime time, char date_separator = '-', char hms_separator = ':'); DN_API DN_U64 DN_OS_DateUnixTimeNs ();
DN_API DN_U64 DN_OS_DateUnixTimeNs (); #define DN_OS_DateUnixTimeUs() (DN_OS_DateUnixTimeNs() / 1000)
#define DN_OS_DateUnixTimeUs() (DN_OS_DateUnixTimeNs() / 1000) #define DN_OS_DateUnixTimeMs() (DN_OS_DateUnixTimeNs() / (1000 * 1000))
#define DN_OS_DateUnixTimeMs() (DN_OS_DateUnixTimeNs() / (1000 * 1000)) #define DN_OS_DateUnixTimeS() (DN_OS_DateUnixTimeNs() / (1000 * 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_OSDateTime DN_OS_DateUnixTimeSToDate (DN_U64 time); DN_API DN_U64 DN_OS_DateLocalToUnixTimeS (DN_OSDateTime date);
DN_API DN_U64 DN_OS_DateLocalToUnixTimeS(DN_OSDateTime date); DN_API DN_U64 DN_OS_DateToUnixTimeS (DN_OSDateTime date);
DN_API DN_U64 DN_OS_DateToUnixTimeS (DN_OSDateTime date); DN_API bool DN_OS_DateIsValid (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 void DN_OS_GenBytesSecure (void *buffer, DN_U32 size); DN_API bool DN_OS_SetEnvVar (DN_Str8 name, DN_Str8 value);
DN_API bool DN_OS_SetEnvVar (DN_Str8 name, DN_Str8 value); DN_API DN_OSDiskSpace DN_OS_DiskSpace (DN_Str8 path);
DN_API DN_OSDiskSpace DN_OS_DiskSpace (DN_Str8 path); DN_API DN_Str8 DN_OS_EXEPath (DN_Arena *arena);
DN_API DN_Str8 DN_OS_EXEPath (DN_Arena *arena); DN_API DN_Str8 DN_OS_EXEDir (DN_Arena *arena);
DN_API DN_Str8 DN_OS_EXEDir (DN_Arena *arena); #define DN_OS_EXEDirFromTLS() DN_OS_EXEDir(DN_OS_TLSTopArena())
#define DN_OS_EXEDirFromTLS() DN_OS_EXEDir(DN_OS_TLSTopArena()) DN_API void DN_OS_SleepMs (DN_UInt milliseconds);
DN_API void DN_OS_SleepMs (DN_UInt milliseconds);
// NOTE: Counters ////////////////////////////////////////////////////////////////////////////////// DN_API DN_U64 DN_OS_PerfCounterNow ();
DN_API DN_U64 DN_OS_PerfCounterNow (); DN_API DN_U64 DN_OS_PerfCounterFrequency ();
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_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_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_PerfCounterUs (DN_U64 begin, uint64_t end); DN_API DN_F64 DN_OS_PerfCounterNs (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 DN_OSTimer DN_OS_TimerBegin (); DN_API void DN_OS_TimerEnd (DN_OSTimer *timer);
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_TimerS (DN_OSTimer timer); DN_API DN_F64 DN_OS_TimerMs (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_TimerUs (DN_OSTimer timer); DN_API DN_F64 DN_OS_TimerNs (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);
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);
// NOTE: R/W Stream API //////////////////////////////////////////////////////////////////////////// DN_API bool DN_OS_FileCopy (DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *err);
DN_API DN_OSFile DN_OS_FileOpen (DN_Str8 path, DN_OSFileOpen open_mode, DN_OSFileAccess access, DN_OSErrSink *err); DN_API bool DN_OS_FileMove (DN_Str8 src, DN_Str8 dest, bool overwrite, 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);
// NOTE: R/W Entire File /////////////////////////////////////////////////////////////////////////// DN_API DN_OSFile DN_OS_FileOpen (DN_Str8 path, DN_OSFileOpen open_mode, DN_OSFileAccess access, DN_OSErrSink *err);
DN_API DN_Str8 DN_OS_ReadAll (DN_Arena *arena, DN_Str8 path, DN_OSErrSink *err); DN_API DN_OSFileRead DN_OS_FileRead (DN_OSFile *file, void *buffer, DN_USize size, DN_OSErrSink *err);
#define DN_OS_ReadAllFromTLS(...) DN_OS_ReadAll(DN_OS_TLSTopArena(), ##__VA_ARGS__) DN_API bool DN_OS_FileWritePtr (DN_OSFile *file, void const *data, DN_USize size, DN_OSErrSink *err);
DN_API bool DN_OS_WriteAll (DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *err); DN_API bool DN_OS_FileWrite (DN_OSFile *file, 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_FileWriteFV (DN_OSFile *file, 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_FileWriteF (DN_OSFile *file, 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_FileFlush (DN_OSFile *file, 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 void DN_OS_FileClose (DN_OSFile *file);
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_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); 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__) DN_API bool DN_OS_PathAddRefTLS (DN_OSPath *fs_path, DN_Str8 path);
#define DN_OS_PathAddRefFromFrame(...) DN_OS_PathAddRef(DN_OS_TLSFrameArena(), ##__VA_ARGS__) 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); 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_PathAddFromTLS(...) DN_OS_PathAdd(DN_OS_TLSTopArena(), ##__VA_ARGS__)
#define DN_OS_PathAddFromFrame(...) DN_OS_PathAdd(DN_OS_TLSFrameArena(), ##__VA_ARGS__) #define DN_OS_PathAddFromFrame(...) DN_OS_PathAdd(DN_OS_TLSFrameArena(), ##__VA_ARGS__)
@ -5928,49 +5932,48 @@ 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_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) #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 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_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_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_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_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);
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())
#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 DN_OSSemaphore DN_OS_SemaphoreInit (DN_U32 initial_count);
DN_API bool DN_OS_SemaphoreIsValid (DN_OSSemaphore *semaphore); DN_API bool DN_OS_SemaphoreIsValid (DN_OSSemaphore *semaphore);
DN_API void DN_OS_SemaphoreDeinit (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 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_OSSemaphoreWaitResult DN_OS_SemaphoreWait (DN_OSSemaphore *semaphore, DN_U32 timeout_ms);
DN_API DN_OSMutex DN_OS_MutexInit (); DN_API DN_OSMutex DN_OS_MutexInit ();
DN_API void DN_OS_MutexDeinit(DN_OSMutex *mutex); DN_API void DN_OS_MutexDeinit (DN_OSMutex *mutex);
DN_API void DN_OS_MutexLock (DN_OSMutex *mutex); DN_API void DN_OS_MutexLock (DN_OSMutex *mutex);
DN_API void DN_OS_MutexUnlock(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)) #define DN_OS_MutexScope (mutex) DN_DeferLoop(DN_OS_MutexLock(mutex), DN_OS_MutexUnlock(mutex))
DN_API DN_OSConditionVariable DN_OS_ConditionVariableInit (); DN_API DN_OSConditionVariable DN_OS_ConditionVariableInit ();
DN_API void DN_OS_ConditionVariableDeinit (DN_OSConditionVariable *cv); 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_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 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_ConditionVariableSignal (DN_OSConditionVariable *cv);
DN_API void DN_OS_ConditionVariableBroadcast(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 bool DN_OS_ThreadInit (DN_OSThread *thread, DN_OSThreadFunc *func, void *user_context);
DN_API void DN_OS_ThreadDeinit(DN_OSThread *thread); DN_API void DN_OS_ThreadDeinit (DN_OSThread *thread);
DN_API DN_U32 DN_OS_ThreadID (); DN_API DN_U32 DN_OS_ThreadID ();
DN_API void DN_OS_ThreadSetName(DN_Str8 name); 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_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_HttpRequestWait (DN_OSHttpResponse *response);
DN_API void DN_OS_HttpRequestFree (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 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) #endif // !defined(DN_OS_H)
// DN: Single header generator inlined this file => #include "OS/dn_os_allocator.h" // DN: Single header generator inlined this file => #include "OS/dn_os_allocator.h"
#if !defined(DN_OS_ALLOCATOR_H) #if !defined(DN_OS_ALLOCATOR_H)
#define 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); DN_API DN_Arena DN_Arena_FromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags);
#endif // !defined(DN_OS_ALLOCATOR_H) #endif // !defined(DN_OS_ALLOCATOR_H)
@ -6316,22 +6319,29 @@ DN_API void DN_Core_SetProfiler (DN_Profiler
#if !defined(DN_MATH_H) #if !defined(DN_MATH_H)
#define DN_MATH_H #define DN_MATH_H
// DN: Single header generator commented out this header => #include "../dn_base_inc.h"
DN_MSVC_WARNING_PUSH DN_MSVC_WARNING_PUSH
DN_MSVC_WARNING_DISABLE(4201) // warning C4201: nonstandard extension used: nameless struct/union DN_MSVC_WARNING_DISABLE(4201) // warning C4201: nonstandard extension used: nameless struct/union
#if !defined(DN_NO_V2)
// NOTE: DN_V2 /////////////////////////////////////////////////////////////////////////////////////
union DN_V2I32 union DN_V2I32
{ {
struct { int32_t x, y; }; struct { DN_I32 x, y; };
struct { int32_t w, h; }; struct { DN_I32 w, h; };
int32_t data[2]; DN_I32 data[2];
}; };
union DN_V2U16 union DN_V2U16
{ {
struct { uint16_t x, y; }; struct { DN_U16 x, y; };
struct { uint16_t w, h; }; struct { DN_U16 w, h; };
uint16_t data[2]; DN_U16 data[2];
};
union DN_V2U32
{
struct { DN_U32 x, y; };
struct { DN_U32 w, h; };
DN_U32 data[2];
}; };
union DN_V2F32 union DN_V2F32
@ -6340,10 +6350,7 @@ union DN_V2F32
struct { DN_F32 w, h; }; struct { DN_F32 w, h; };
DN_F32 data[2]; DN_F32 data[2];
}; };
#endif // !defined(DN_NO_V2)
#if !defined(DN_NO_V3)
// NOTE: DN_V3 /////////////////////////////////////////////////////////////////////////////////////
union DN_V3F32 union DN_V3F32
{ {
struct { DN_F32 x, y, z; }; struct { DN_F32 x, y, z; };
@ -6351,10 +6358,7 @@ union DN_V3F32
DN_F32 data[3]; DN_F32 data[3];
}; };
#endif // !defined(DN_NO_V3)
#if !defined(DN_NO_V4)
// NOTE: DN_V4 /////////////////////////////////////////////////////////////////////////////////////
union DN_V4F32 union DN_V4F32
{ {
struct { DN_F32 x, y, z, w; }; struct { DN_F32 x, y, z, w; };
@ -6365,29 +6369,19 @@ union DN_V4F32
#endif #endif
DN_F32 data[4]; DN_F32 data[4];
}; };
#endif // !defined(DN_NO_V4)
DN_MSVC_WARNING_POP DN_MSVC_WARNING_POP
#if !defined(DN_NO_M4)
// NOTE: DN_M4 /////////////////////////////////////////////////////////////////////////////////////
struct DN_M4 struct DN_M4
{ {
DN_F32 columns[4][4]; // Column major matrix DN_F32 columns[4][4]; // Column major matrix
}; };
#endif // !defined(DN_M4)
// NOTE: DN_M2x3 ///////////////////////////////////////////////////////////////////////////////////
union DN_M2x3 union DN_M2x3
{ {
DN_F32 e[6]; DN_F32 e[6];
DN_F32 row[2][3]; DN_F32 row[2][3];
}; };
// NOTE: DN_Rect ///////////////////////////////////////////////////////////////////////////////////
#if !defined(DN_NO_RECT)
#if defined(DN_NO_V2)
#error "Rectangles requires V2, DN_NO_V2 must not be defined"
#endif
struct DN_Rect struct DN_Rect
{ {
DN_V2F32 pos, size; DN_V2F32 pos, size;
@ -6417,10 +6411,7 @@ struct DN_RectCut
DN_Rect* rect; DN_Rect* rect;
DN_RectCutSide side; DN_RectCutSide side;
}; };
#endif // !defined(DN_NO_RECT)
// NOTE: Other /////////////////////////////////////////////////////////////////////////////////////
// NOTE: API
struct DN_RaycastLineIntersectV2Result struct DN_RaycastLineIntersectV2Result
{ {
bool hit; // True if there was an intersection, false if the lines are parallel bool hit; // True if there was an intersection, false if the lines are parallel
@ -6428,13 +6419,11 @@ struct DN_RaycastLineIntersectV2Result
DN_F32 t_b; // Distance along `dir_b` that the intersection occurred, e.g. `origin_b + (dir_b * t_b)` DN_F32 t_b; // Distance along `dir_b` that the intersection occurred, e.g. `origin_b + (dir_b * t_b)`
}; };
#if !defined(DN_NO_V2) #define DN_V2I32_Zero DN_Literal(DN_V2I32){{(int32_t)(0), (int32_t)(0)}}
// NOTE: DN_V2 ///////////////////////////////////////////////////////////////////////////////////// #define DN_V2I32_One DN_Literal(DN_V2I32){{(int32_t)(1), (int32_t)(1)}}
#define DN_V2I32_Zero DN_LITERAL(DN_V2I32){{(int32_t)(0), (int32_t)(0)}} #define DN_V2I32_From1N(x) DN_Literal(DN_V2I32){{(int32_t)(x), (int32_t)(x)}}
#define DN_V2I32_One DN_LITERAL(DN_V2I32){{(int32_t)(1), (int32_t)(1)}} #define DN_V2I32_From2N(x, y) DN_Literal(DN_V2I32){{(int32_t)(x), (int32_t)(y)}}
#define DN_V2I32_From1N(x) DN_LITERAL(DN_V2I32){{(int32_t)(x), (int32_t)(x)}} #define DN_V2I32_InitV2(xy) DN_Literal(DN_V2I32){{(int32_t)(xy).x, (int32_t)(xy).y}}
#define DN_V2I32_From2N(x, y) DN_LITERAL(DN_V2I32){{(int32_t)(x), (int32_t)(y)}}
#define DN_V2I32_InitV2(xy) DN_LITERAL(DN_V2I32){{(int32_t)(xy).x, (int32_t)(xy).y}}
DN_API bool operator!= (DN_V2I32 lhs, DN_V2I32 rhs); DN_API bool operator!= (DN_V2I32 lhs, DN_V2I32 rhs);
DN_API bool operator== (DN_V2I32 lhs, DN_V2I32 rhs); DN_API bool operator== (DN_V2I32 lhs, DN_V2I32 rhs);
@ -6464,10 +6453,10 @@ DN_API DN_V2I32 DN_V2I32_Min (DN_V2I32 a, DN
DN_API DN_V2I32 DN_V2I32_Max (DN_V2I32 a, DN_V2I32 b); DN_API DN_V2I32 DN_V2I32_Max (DN_V2I32 a, DN_V2I32 b);
DN_API DN_V2I32 DN_V2I32_Abs (DN_V2I32 a); DN_API DN_V2I32 DN_V2I32_Abs (DN_V2I32 a);
#define DN_V2U16_Zero DN_LITERAL(DN_V2U16){{(uint16_t)(0), (uint16_t)(0)}} #define DN_V2U16_Zero DN_Literal(DN_V2U16){{(uint16_t)(0), (uint16_t)(0)}}
#define DN_V2U16_One DN_LITERAL(DN_V2U16){{(uint16_t)(1), (uint16_t)(1)}} #define DN_V2U16_One DN_Literal(DN_V2U16){{(uint16_t)(1), (uint16_t)(1)}}
#define DN_V2U16_From1N(x) DN_LITERAL(DN_V2U16){{(uint16_t)(x), (uint16_t)(x)}} #define DN_V2U16_From1N(x) DN_Literal(DN_V2U16){{(uint16_t)(x), (uint16_t)(x)}}
#define DN_V2U16_From2N(x, y) DN_LITERAL(DN_V2U16){{(uint16_t)(x), (uint16_t)(y)}} #define DN_V2U16_From2N(x, y) DN_Literal(DN_V2U16){{(uint16_t)(x), (uint16_t)(y)}}
DN_API bool operator!= (DN_V2U16 lhs, DN_V2U16 rhs); DN_API bool operator!= (DN_V2U16 lhs, DN_V2U16 rhs);
DN_API bool operator== (DN_V2U16 lhs, DN_V2U16 rhs); DN_API bool operator== (DN_V2U16 lhs, DN_V2U16 rhs);
@ -6492,11 +6481,11 @@ DN_API DN_V2U16 & operator/= (DN_V2U16& lhs,
DN_API DN_V2U16 & operator-= (DN_V2U16& lhs, DN_V2U16 rhs); DN_API DN_V2U16 & operator-= (DN_V2U16& lhs, DN_V2U16 rhs);
DN_API DN_V2U16 & operator+= (DN_V2U16& lhs, DN_V2U16 rhs); DN_API DN_V2U16 & operator+= (DN_V2U16& lhs, DN_V2U16 rhs);
#define DN_V2F32_Zero DN_LITERAL(DN_V2F32){{(DN_F32)(0), (DN_F32)(0)}} #define DN_V2F32_Zero DN_Literal(DN_V2F32){{(DN_F32)(0), (DN_F32)(0)}}
#define DN_V2F32_One DN_LITERAL(DN_V2F32){{(DN_F32)(1), (DN_F32)(1)}} #define DN_V2F32_One DN_Literal(DN_V2F32){{(DN_F32)(1), (DN_F32)(1)}}
#define DN_V2F32_From1N(x) DN_LITERAL(DN_V2F32){{(DN_F32)(x), (DN_F32)(x)}} #define DN_V2F32_From1N(x) DN_Literal(DN_V2F32){{(DN_F32)(x), (DN_F32)(x)}}
#define DN_V2F32_From2N(x, y) DN_LITERAL(DN_V2F32){{(DN_F32)(x), (DN_F32)(y)}} #define DN_V2F32_From2N(x, y) DN_Literal(DN_V2F32){{(DN_F32)(x), (DN_F32)(y)}}
#define DN_V2F32_FromV2I32(xy) DN_LITERAL(DN_V2F32){{(DN_F32)(xy).x, (DN_F32)(xy).y}} #define DN_V2F32_FromV2I32(xy) DN_Literal(DN_V2F32){{(DN_F32)(xy).x, (DN_F32)(xy).y}}
DN_API bool operator!= (DN_V2F32 lhs, DN_V2F32 rhs); DN_API bool operator!= (DN_V2F32 lhs, DN_V2F32 rhs);
DN_API bool operator== (DN_V2F32 lhs, DN_V2F32 rhs); DN_API bool operator== (DN_V2F32 lhs, DN_V2F32 rhs);
@ -6559,12 +6548,10 @@ DN_API DN_V2F32 DN_V2F32_Normalise (DN_V2F32 a);
DN_API DN_V2F32 DN_V2F32_Perpendicular (DN_V2F32 a); DN_API DN_V2F32 DN_V2F32_Perpendicular (DN_V2F32 a);
DN_API DN_V2F32 DN_V2F32_Reflect (DN_V2F32 in, DN_V2F32 surface); DN_API DN_V2F32 DN_V2F32_Reflect (DN_V2F32 in, DN_V2F32 surface);
DN_API DN_F32 DN_V2F32_Area (DN_V2F32 a); DN_API DN_F32 DN_V2F32_Area (DN_V2F32 a);
#endif // !defined(DN_NO_V2)
#if !defined(DN_NO_V3) #define DN_V3F32_From1N(x) DN_Literal(DN_V3F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}}
// NOTE: DN_V3 ///////////////////////////////////////////////////////////////////////////////////// #define DN_V3F32_From3N(x, y, z) DN_Literal(DN_V3F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z)}}
#define DN_V3F32_From1N(x) DN_LITERAL(DN_V3F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}} #define DN_V3F32_FromV2F32And1N(xy, z) DN_Literal(DN_V3F32){{(DN_F32)(xy.x), (DN_F32)(xy.y), (DN_F32)(z)}}
#define DN_V3F32_From3N(x, y, z) DN_LITERAL(DN_V3F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z)}}
#define DN_V3F32_FromV2F32And1N(xy, z) DN_LITERAL(DN_V3F32){{(DN_F32)(xy.x), (DN_F32)(xy.y), (DN_F32)(z)}}
DN_API bool operator== (DN_V3F32 lhs, DN_V3F32 rhs); DN_API bool operator== (DN_V3F32 lhs, DN_V3F32 rhs);
DN_API bool operator!= (DN_V3F32 lhs, DN_V3F32 rhs); DN_API bool operator!= (DN_V3F32 lhs, DN_V3F32 rhs);
@ -6592,19 +6579,17 @@ DN_API DN_V3F32 & operator+= (DN_V3F32 &lhs,
DN_API DN_F32 DN_V3F32_LengthSq (DN_V3F32 a); DN_API DN_F32 DN_V3F32_LengthSq (DN_V3F32 a);
DN_API DN_F32 DN_V3F32_Length (DN_V3F32 a); DN_API DN_F32 DN_V3F32_Length (DN_V3F32 a);
DN_API DN_V3F32 DN_V3F32_Normalise (DN_V3F32 a); DN_API DN_V3F32 DN_V3F32_Normalise (DN_V3F32 a);
#endif // !defined(DN_NO_V3)
#if !defined(DN_NO_V4)
DN_U32 const DN_V4_R_MASK_U32 = 0xFF000000; DN_U32 const DN_V4_R_MASK_U32 = 0xFF000000;
DN_U32 const DN_V4_G_MASK_U32 = 0x00FF0000; DN_U32 const DN_V4_G_MASK_U32 = 0x00FF0000;
DN_U32 const DN_V4_B_MASK_U32 = 0x0000FF00; DN_U32 const DN_V4_B_MASK_U32 = 0x0000FF00;
DN_U32 const DN_V4_A_MASK_U32 = 0x000000FF; DN_U32 const DN_V4_A_MASK_U32 = 0x000000FF;
// NOTE: DN_V4 ///////////////////////////////////////////////////////////////////////////////////// #define DN_V4F32_From1N(x) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}}
#define DN_V4F32_From1N(x) DN_LITERAL(DN_V4F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}} #define DN_V4F32_From4N(x, y, z, w) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z), (DN_F32)(w)}}
#define DN_V4F32_From4N(x, y, z, w) DN_LITERAL(DN_V4F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z), (DN_F32)(w)}} #define DN_V4F32_FromV3And1N(xyz, w) DN_Literal(DN_V4F32){{xyz.x, xyz.y, xyz.z, w}}
#define DN_V4F32_FromV3And1N(xyz, w) DN_LITERAL(DN_V4F32){{xyz.x, xyz.y, xyz.z, w}} #define DN_V4F32_FromRGBAU8(r, g, b, a) DN_Literal(DN_V4F32){{r / 255.f, g / 255.f, b / 255.f, a / 255.f}}
#define DN_V4F32_FromRGBAU8(r, g, b, a) DN_LITERAL(DN_V4F32){{r / 255.f, g / 255.f, b / 255.f, a / 255.f}} #define DN_V4F32_FromRGBU8(r, g, b) DN_Literal(DN_V4F32){{r / 255.f, g / 255.f, b / 255.f, 1.f}}
#define DN_V4F32_FromRGBU8(r, g, b) DN_LITERAL(DN_V4F32){{r / 255.f, g / 255.f, b / 255.f, 1.f}}
DN_API DN_V4F32 DN_V4F32_FromRGBU32(DN_U32 u32); DN_API DN_V4F32 DN_V4F32_FromRGBU32(DN_U32 u32);
DN_API DN_V4F32 DN_V4F32_FromRGBAU32(DN_U32 u32); DN_API DN_V4F32 DN_V4F32_FromRGBAU32(DN_U32 u32);
#define DN_V4F32_FromV4Alpha(v4, alpha) DN_V4F32_FromV3And1N(v4.xyz, alpha) #define DN_V4F32_FromV4Alpha(v4, alpha) DN_V4F32_FromV3And1N(v4.xyz, alpha)
@ -6626,9 +6611,7 @@ DN_API DN_V4F32 & operator*= (DN_V4F32 &lhs,
DN_API DN_V4F32 & operator-= (DN_V4F32 &lhs, DN_V4F32 rhs); DN_API DN_V4F32 & operator-= (DN_V4F32 &lhs, DN_V4F32 rhs);
DN_API DN_V4F32 & operator+= (DN_V4F32 &lhs, DN_V4F32 rhs); DN_API DN_V4F32 & operator+= (DN_V4F32 &lhs, DN_V4F32 rhs);
DN_API DN_F32 DN_V4F32_Dot (DN_V4F32 a, DN_V4F32 b); DN_API DN_F32 DN_V4F32_Dot (DN_V4F32 a, DN_V4F32 b);
#endif // !defined(DN_NO_V4)
#if !defined(DN_NO_M4)
// NOTE: DN_M4 /////////////////////////////////////////////////////////////////////////////////////
DN_API DN_M4 DN_M4_Identity (); DN_API DN_M4 DN_M4_Identity ();
DN_API DN_M4 DN_M4_ScaleF (DN_F32 x, DN_F32 y, DN_F32 z); DN_API DN_M4 DN_M4_ScaleF (DN_F32 x, DN_F32 y, DN_F32 z);
DN_API DN_M4 DN_M4_Scale (DN_V3F32 xyz); DN_API DN_M4 DN_M4_Scale (DN_V3F32 xyz);
@ -6647,8 +6630,7 @@ DN_API DN_M4 DN_M4_SubF (DN_M4 lhs, DN_
DN_API DN_M4 DN_M4_MulF (DN_M4 lhs, DN_F32 rhs); DN_API DN_M4 DN_M4_MulF (DN_M4 lhs, DN_F32 rhs);
DN_API DN_M4 DN_M4_DivF (DN_M4 lhs, DN_F32 rhs); DN_API DN_M4 DN_M4_DivF (DN_M4 lhs, DN_F32 rhs);
DN_API DN_Str8x256 DN_M4_ColumnMajorString (DN_M4 mat); DN_API DN_Str8x256 DN_M4_ColumnMajorString (DN_M4 mat);
#endif // !defined(DN_NO_M4)
// NOTE: DN_M2x3 ///////////////////////////////////////////////////////////////////////////////////
DN_API bool operator== (DN_M2x3 const &lhs, DN_M2x3 const &rhs); DN_API bool operator== (DN_M2x3 const &lhs, DN_M2x3 const &rhs);
DN_API bool operator!= (DN_M2x3 const &lhs, DN_M2x3 const &rhs); DN_API bool operator!= (DN_M2x3 const &lhs, DN_M2x3 const &rhs);
DN_API DN_M2x3 DN_M2x3_Identity (); DN_API DN_M2x3 DN_M2x3_Identity ();
@ -6658,10 +6640,9 @@ DN_API DN_M2x3 DN_M2x3_Rotate (DN_F32 radians
DN_API DN_M2x3 DN_M2x3_Mul (DN_M2x3 m1, DN_M2x3 m2); DN_API DN_M2x3 DN_M2x3_Mul (DN_M2x3 m1, DN_M2x3 m2);
DN_API DN_V2F32 DN_M2x3_Mul2F32 (DN_M2x3 m1, DN_F32 x, DN_F32 y); DN_API DN_V2F32 DN_M2x3_Mul2F32 (DN_M2x3 m1, DN_F32 x, DN_F32 y);
DN_API DN_V2F32 DN_M2x3_MulV2 (DN_M2x3 m1, DN_V2F32 v2); DN_API DN_V2F32 DN_M2x3_MulV2 (DN_M2x3 m1, DN_V2F32 v2);
#if !defined(DN_NO_RECT)
// NOTE: DN_Rect /////////////////////////////////////////////////////////////////////////////////// #define DN_Rect_From2V2(pos, size) DN_Literal(DN_Rect){(pos), (size)}
#define DN_Rect_From2V2(pos, size) DN_LITERAL(DN_Rect){(pos), (size)} #define DN_Rect_From4N(x, y, w, h) DN_Literal(DN_Rect){DN_Literal(DN_V2F32){{x, y}}, DN_Literal(DN_V2F32){{w, h}}}
#define DN_Rect_From4N(x, y, w, h) DN_LITERAL(DN_Rect){DN_LITERAL(DN_V2F32){{x, y}}, DN_LITERAL(DN_V2F32){{w, h}}}
DN_API bool operator== (const DN_Rect& lhs, const DN_Rect& rhs); DN_API bool operator== (const DN_Rect& lhs, const DN_Rect& rhs);
DN_API DN_V2F32 DN_Rect_Center (DN_Rect rect); DN_API DN_V2F32 DN_Rect_Center (DN_Rect rect);
@ -6696,13 +6677,12 @@ DN_API DN_Rect DN_Rect_CutBottomClip (DN_Rect *rect,
#define DN_Rect_CutBottomNoClip(rect, amount) DN_Rect_CutBottomClip(rect, amount, DN_RectCutClip_No) #define DN_Rect_CutBottomNoClip(rect, amount) DN_Rect_CutBottomClip(rect, amount, DN_RectCutClip_No)
DN_API DN_Rect DN_RectCut_Cut (DN_RectCut rect_cut, DN_V2F32 size, DN_RectCutClip clip); DN_API DN_Rect DN_RectCut_Cut (DN_RectCut rect_cut, DN_V2F32 size, DN_RectCutClip clip);
#define DN_RectCut_Init(rect, side) DN_LITERAL(DN_RectCut){rect, side} #define DN_RectCut_Init(rect, side) DN_Literal(DN_RectCut){rect, side}
#define DN_RectCut_Left(rect) DN_LITERAL(DN_RectCut){rect, DN_RectCutSide_Left} #define DN_RectCut_Left(rect) DN_Literal(DN_RectCut){rect, DN_RectCutSide_Left}
#define DN_RectCut_Right(rect) DN_LITERAL(DN_RectCut){rect, DN_RectCutSide_Right} #define DN_RectCut_Right(rect) DN_Literal(DN_RectCut){rect, DN_RectCutSide_Right}
#define DN_RectCut_Top(rect) DN_LITERAL(DN_RectCut){rect, DN_RectCutSide_Top} #define DN_RectCut_Top(rect) DN_Literal(DN_RectCut){rect, DN_RectCutSide_Top}
#define DN_RectCut_Bottom(rect) DN_LITERAL(DN_RectCut){rect, DN_RectCutSide_Bottom} #define DN_RectCut_Bottom(rect) DN_Literal(DN_RectCut){rect, DN_RectCutSide_Bottom}
#endif // !defined(DN_NO_RECT)
// NOTE: Other /////////////////////////////////////////////////////////////////////////////////////
DN_API DN_RaycastLineIntersectV2Result DN_Raycast_LineIntersectV2(DN_V2F32 origin_a, DN_V2F32 dir_a, DN_V2F32 origin_b, DN_V2F32 dir_b); DN_API DN_RaycastLineIntersectV2Result DN_Raycast_LineIntersectV2(DN_V2F32 origin_a, DN_V2F32 dir_a, DN_V2F32 origin_b, DN_V2F32 dir_b);
DN_API DN_V2F32 DN_Lerp_V2F32 (DN_V2F32 a, DN_F32 t, DN_V2F32 b); DN_API DN_V2F32 DN_Lerp_V2F32 (DN_V2F32 a, DN_F32 t, DN_V2F32 b);
DN_API DN_F32 DN_Lerp_F32 (DN_F32 a, DN_F32 t, DN_F32 b); DN_API DN_F32 DN_Lerp_F32 (DN_F32 a, DN_F32 t, DN_F32 b);

View File

@ -109,9 +109,9 @@
#endif #endif
#if defined(__cplusplus) #if defined(__cplusplus)
#define DN_LITERAL(T) T #define DN_Literal(T) T
#else #else
#define DN_LITERAL(T) (T) #define DN_Literal(T) (T)
#endif #endif
// NOTE: Thread Locals ///////////////////////////////////////////////////////////////////////////// // NOTE: Thread Locals /////////////////////////////////////////////////////////////////////////////

View File

@ -68,8 +68,8 @@ DN_API DN_CVTU64Str8 DN_CVT_Str8FromU64 (DN_U6
DN_API DN_CVTU64Bytes DN_CVT_BytesFromU64 (DN_U64 bytes, DN_CVTBytesType type); DN_API DN_CVTU64Bytes DN_CVT_BytesFromU64 (DN_U64 bytes, DN_CVTBytesType type);
#define DN_CVT_BytesFromU64Auto(bytes) DN_CVT_BytesFromU64(bytes, DN_CVTBytesType_Auto) #define DN_CVT_BytesFromU64Auto(bytes) DN_CVT_BytesFromU64(bytes, DN_CVTBytesType_Auto)
DN_API DN_Str8 DN_CVT_BytesStr8FromU64 (DN_Arena *arena, DN_U64 bytes, DN_CVTBytesType type); DN_API DN_Str8 DN_CVT_BytesStr8FromU64 (DN_Arena *arena, DN_U64 bytes, DN_CVTBytesType type);
#define DN_CVT_BytesStr8FromU64Auto(arena, bytes) DN_CVT_BytesStr8FromU64(arena, bytes, DN_CVTBytesType_Auto)
#define DN_CVT_BytesStr8FromTLS(bytes, type) DN_CVT_BytesStr8FromU64(DN_OS_TLSTopArena(), bytes, type) #define DN_CVT_BytesStr8FromTLS(bytes, type) DN_CVT_BytesStr8FromU64(DN_OS_TLSTopArena(), bytes, type)
#define DN_CVT_BytesStr8FromU64Auto(arena, bytes) DN_CVT_BytesStr8FromU64(arena, bytes, DN_CVTBytesType_Auto)
#define DN_CVT_BytesStr8FromU64AutoTLS(bytes) DN_CVT_BytesStr8FromU64(DN_OS_TLSTopArena(), bytes, DN_CVTBytesType_Auto) #define DN_CVT_BytesStr8FromU64AutoTLS(bytes) DN_CVT_BytesStr8FromU64(DN_OS_TLSTopArena(), bytes, DN_CVTBytesType_Auto)
#define DN_CVT_BytesStr8FromU64Frame(bytes, type) DN_CVT_BytesStr8FromU64(DN_OS_TLSFrameArena(), bytes, type) #define DN_CVT_BytesStr8FromU64Frame(bytes, type) DN_CVT_BytesStr8FromU64(DN_OS_TLSFrameArena(), bytes, type)
#define DN_CVT_BytesStr8FromU64AutoFrame(bytes) DN_CVT_BytesStr8FromU64(DN_OS_TLSFrameArena(), bytes, DN_CVTBytesType_Auto) #define DN_CVT_BytesStr8FromU64AutoFrame(bytes) DN_CVT_BytesStr8FromU64(DN_OS_TLSFrameArena(), bytes, DN_CVTBytesType_Auto)

View File

@ -59,6 +59,12 @@ enum DN_MemPage_
#define DN_ARENA_COMMIT_SIZE DN_Kilobytes(64) #define DN_ARENA_COMMIT_SIZE DN_Kilobytes(64)
#endif #endif
enum DN_Allocator
{
DN_Allocator_Arena,
DN_Allocator_Pool,
};
struct DN_ArenaBlock struct DN_ArenaBlock
{ {
DN_ArenaBlock *prev; DN_ArenaBlock *prev;

View File

@ -68,6 +68,16 @@ DN_API DN_Str8 DN_Str8_Alloc(DN_Arena *arena, DN_USize size, DN_ZeroMem zero_mem
return result; return result;
} }
DN_API DN_Str8 DN_Str8_AllocPool(DN_Pool *pool, DN_USize size)
{
DN_Str8 result = {};
result.data = DN_Pool_NewArray(pool, char, size + 1);
if (result.data)
result.size = size;
result.data[result.size] = 0;
return result;
}
DN_API DN_Str8 DN_Str8_FromCStr8(char const *src) DN_API DN_Str8 DN_Str8_FromCStr8(char const *src)
{ {
DN_USize size = DN_CStr8_Size(src); DN_USize size = DN_CStr8_Size(src);
@ -84,6 +94,21 @@ DN_API DN_Str8 DN_Str8_FromF(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...
return result; return result;
} }
DN_API DN_Str8 DN_Str8_FromFPool(DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
DN_USize size = DN_CStr8_FVSize(fmt, args);
va_end(args);
DN_Str8 result = {};
if (size)
result = DN_Str8_AllocPool(pool, size);
if (result.data)
DN_VSNPrintF(result.data, DN_SaturateCastISizeToInt(size + 1 /*null-terminator*/), fmt, args);
return result;
}
DN_API DN_Str8 DN_Str8_FromFV(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args) DN_API DN_Str8 DN_Str8_FromFV(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args)
{ {
DN_Str8 result = {}; DN_Str8 result = {};

View File

@ -138,16 +138,17 @@ DN_API DN_Str8 DN_Str8_Alloc (DN_Arena *aren
DN_API DN_Str8 DN_Str8_FromCStr8 (char const *src); DN_API DN_Str8 DN_Str8_FromCStr8 (char const *src);
DN_API DN_Str8 DN_Str8_FromF (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...); DN_API DN_Str8 DN_Str8_FromF (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...);
DN_API DN_Str8 DN_Str8_FromFV (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8 DN_Str8_FromFV (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args);
DN_API DN_Str8 DN_Str8_FromFPool (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...);
DN_API DN_Str8 DN_Str8_FromStr8 (DN_Arena *arena, DN_Str8 string); DN_API DN_Str8 DN_Str8_FromStr8 (DN_Arena *arena, DN_Str8 string);
DN_API bool DN_Str8_IsAll (DN_Str8 string, DN_Str8IsAll is_all); DN_API bool DN_Str8_IsAll (DN_Str8 string, DN_Str8IsAll is_all);
DN_API char * DN_Str8_End (DN_Str8 string); DN_API char * DN_Str8_End (DN_Str8 string);
DN_API DN_Str8 DN_Str8_Slice (DN_Str8 string, DN_USize offset, DN_USize size); DN_API DN_Str8 DN_Str8_Slice (DN_Str8 string, DN_USize offset, DN_USize size);
DN_API DN_Str8 DN_Str8_Advance (DN_Str8 string, DN_USize amount); DN_API DN_Str8 DN_Str8_Advance (DN_Str8 string, DN_USize amount);
DN_API DN_Str8 DN_Str8_NextLine (DN_Str8 string); DN_API DN_Str8 DN_Str8_NextLine (DN_Str8 string);
DN_API DN_Str8BSplitResult DN_Str8_BSplitArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size); DN_API DN_Str8BSplitResult DN_Str8_BSplitArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size);
DN_API DN_Str8BSplitResult DN_Str8_BSplit (DN_Str8 string, DN_Str8 find); DN_API DN_Str8BSplitResult DN_Str8_BSplit (DN_Str8 string, DN_Str8 find);
DN_API DN_Str8BSplitResult DN_Str8_BSplitLastArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size); DN_API DN_Str8BSplitResult DN_Str8_BSplitLastArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size);
DN_API DN_Str8BSplitResult DN_Str8_BSplitLast (DN_Str8 string, DN_Str8 find); DN_API DN_Str8BSplitResult DN_Str8_BSplitLast (DN_Str8 string, DN_Str8 find);
DN_API DN_USize DN_Str8_Split (DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_USize splits_count, DN_Str8SplitIncludeEmptyStrings mode); DN_API DN_USize DN_Str8_Split (DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_USize splits_count, DN_Str8SplitIncludeEmptyStrings mode);
DN_API DN_Slice<DN_Str8> DN_Str8_SplitAlloc (DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode); DN_API DN_Slice<DN_Str8> DN_Str8_SplitAlloc (DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode);
DN_API DN_Str8FindResult DN_Str8_FindStr8Array (DN_Str8 string, DN_Str8 const *find, DN_USize find_size, DN_Str8EqCase eq_case); DN_API DN_Str8FindResult DN_Str8_FindStr8Array (DN_Str8 string, DN_Str8 const *find, DN_USize find_size, DN_Str8EqCase eq_case);

View File

@ -322,7 +322,7 @@ void DN_Docs_Demo()
// NOTE: My error sinks are thread-local, so the returned 'error' is // NOTE: My error sinks are thread-local, so the returned 'error' is
// the same as the 'error' value above. // the same as the 'error' value above.
DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil); DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil);
DN_OS_WriteAll(DN_STR8("/path/to/another/file"), DN_STR8("123"), error); DN_OS_FileWriteAll(DN_STR8("/path/to/another/file"), DN_STR8("123"), error);
DN_OS_ErrSinkEndAndLogErrorF(error, "Failed to write to another file"); DN_OS_ErrSinkEndAndLogErrorF(error, "Failed to write to another file");
} }
@ -451,7 +451,7 @@ void DN_Docs_Demo()
// NOTE: DN_OS_DirIterate ///////////////////////////////////////////////////////////////////// // NOTE: DN_OS_DirIterate /////////////////////////////////////////////////////////////////////
// //
// Iterate the files within the passed in folder // Iterate the files within the passed in folder
for (DN_OSDirIterator it = {}; DN_OS_DirIterate(DN_STR8("."), &it);) { for (DN_OSDirIterator it = {}; DN_OS_PathIterateDir(DN_STR8("."), &it);) {
// printf("%.*s\n", DN_STR_FMT(it.file_name)); // printf("%.*s\n", DN_STR_FMT(it.file_name));
} }
@ -473,7 +473,7 @@ void DN_Docs_Demo()
if (0) { if (0) {
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_OSErrSink *error = DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil); DN_OSErrSink *error = DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil);
DN_OS_WriteAllSafe(/*path*/ DN_STR8("C:/Home/my.txt"), /*buffer*/ DN_STR8("Hello world"), error); DN_OS_FileWriteAllSafe(/*path*/ DN_STR8("C:/Home/my.txt"), /*buffer*/ DN_STR8("Hello world"), error);
DN_OS_ErrSinkEndAndLogErrorF(error, ""); DN_OS_ErrSinkEndAndLogErrorF(error, "");
} }

View File

@ -1,8 +1,7 @@
#define DN_MATH_CPP #define DN_MATH_CPP
#if !defined(DN_NO_V2) #include "dn_math.h"
// NOTE: DN_V2 /////////////////////////////////////////////////////////////////////////////////////
// NOTE: DN_V2I32
DN_API bool operator==(DN_V2I32 lhs, DN_V2I32 rhs) DN_API bool operator==(DN_V2I32 lhs, DN_V2I32 rhs)
{ {
bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y); bool result = (lhs.x == rhs.x) && (lhs.y == rhs.y);
@ -159,7 +158,6 @@ DN_API DN_V2I32 DN_V2I32_Abs(DN_V2I32 a)
return result; return result;
} }
// NOTE: DN_V2U16
DN_API bool operator!=(DN_V2U16 lhs, DN_V2U16 rhs) DN_API bool operator!=(DN_V2U16 lhs, DN_V2U16 rhs)
{ {
bool result = !(lhs == rhs); bool result = !(lhs == rhs);
@ -292,7 +290,6 @@ DN_API DN_V2U16 &operator+=(DN_V2U16 &lhs, DN_V2U16 rhs)
return lhs; return lhs;
} }
// NOTE: DN_V2
DN_API bool operator!=(DN_V2F32 lhs, DN_V2F32 rhs) DN_API bool operator!=(DN_V2F32 lhs, DN_V2F32 rhs)
{ {
bool result = !(lhs == rhs); bool result = !(lhs == rhs);
@ -329,7 +326,6 @@ DN_API bool operator>(DN_V2F32 lhs, DN_V2F32 rhs)
return result; return result;
} }
// NOTE: DN_V2F32 operator- //////////////////////////////////////////////////////////////////////////
DN_API DN_V2F32 operator-(DN_V2F32 lhs) DN_API DN_V2F32 operator-(DN_V2F32 lhs)
{ {
DN_V2F32 result = DN_V2F32_From2N(-lhs.x, -lhs.y); DN_V2F32 result = DN_V2F32_From2N(-lhs.x, -lhs.y);
@ -360,7 +356,6 @@ DN_API DN_V2F32 operator-(DN_V2F32 lhs, int32_t rhs)
return result; return result;
} }
// NOTE: DN_V2F32 operator+ //////////////////////////////////////////////////////////////////////////
DN_API DN_V2F32 operator+(DN_V2F32 lhs, DN_V2F32 rhs) DN_API DN_V2F32 operator+(DN_V2F32 lhs, DN_V2F32 rhs)
{ {
DN_V2F32 result = DN_V2F32_From2N(lhs.x + rhs.x, lhs.y + rhs.y); DN_V2F32 result = DN_V2F32_From2N(lhs.x + rhs.x, lhs.y + rhs.y);
@ -385,7 +380,6 @@ DN_API DN_V2F32 operator+(DN_V2F32 lhs, int32_t rhs)
return result; return result;
} }
// NOTE: DN_V2F32 operator* //////////////////////////////////////////////////////////////////////////
DN_API DN_V2F32 operator*(DN_V2F32 lhs, DN_V2F32 rhs) DN_API DN_V2F32 operator*(DN_V2F32 lhs, DN_V2F32 rhs)
{ {
DN_V2F32 result = DN_V2F32_From2N(lhs.x * rhs.x, lhs.y * rhs.y); DN_V2F32 result = DN_V2F32_From2N(lhs.x * rhs.x, lhs.y * rhs.y);
@ -410,7 +404,6 @@ DN_API DN_V2F32 operator*(DN_V2F32 lhs, int32_t rhs)
return result; return result;
} }
// NOTE: DN_V2F32 operator/ //////////////////////////////////////////////////////////////////////////
DN_API DN_V2F32 operator/(DN_V2F32 lhs, DN_V2F32 rhs) DN_API DN_V2F32 operator/(DN_V2F32 lhs, DN_V2F32 rhs)
{ {
DN_V2F32 result = DN_V2F32_From2N(lhs.x / rhs.x, lhs.y / rhs.y); DN_V2F32 result = DN_V2F32_From2N(lhs.x / rhs.x, lhs.y / rhs.y);
@ -435,7 +428,6 @@ DN_API DN_V2F32 operator/(DN_V2F32 lhs, int32_t rhs)
return result; return result;
} }
// NOTE: DN_V2F32 operator*/ /////////////////////////////////////////////////////////////////////////
DN_API DN_V2F32 &operator*=(DN_V2F32 &lhs, DN_V2F32 rhs) DN_API DN_V2F32 &operator*=(DN_V2F32 &lhs, DN_V2F32 rhs)
{ {
lhs = lhs * rhs; lhs = lhs * rhs;
@ -460,7 +452,6 @@ DN_API DN_V2F32 &operator*=(DN_V2F32 &lhs, int32_t rhs)
return lhs; return lhs;
} }
// NOTE: DN_V2F32 operator// /////////////////////////////////////////////////////////////////////////
DN_API DN_V2F32 &operator/=(DN_V2F32 &lhs, DN_V2F32 rhs) DN_API DN_V2F32 &operator/=(DN_V2F32 &lhs, DN_V2F32 rhs)
{ {
lhs = lhs / rhs; lhs = lhs / rhs;
@ -485,7 +476,6 @@ DN_API DN_V2F32 &operator/=(DN_V2F32 &lhs, int32_t rhs)
return lhs; return lhs;
} }
// NOTE: DN_V2F32 operator-/ /////////////////////////////////////////////////////////////////////////
DN_API DN_V2F32 &operator-=(DN_V2F32 &lhs, DN_V2F32 rhs) DN_API DN_V2F32 &operator-=(DN_V2F32 &lhs, DN_V2F32 rhs)
{ {
lhs = lhs - rhs; lhs = lhs - rhs;
@ -510,7 +500,6 @@ DN_API DN_V2F32 &operator-=(DN_V2F32 &lhs, int32_t rhs)
return lhs; return lhs;
} }
// NOTE: DN_V2F32 operator+/ /////////////////////////////////////////////////////////////////////////
DN_API DN_V2F32 &operator+=(DN_V2F32 &lhs, DN_V2F32 rhs) DN_API DN_V2F32 &operator+=(DN_V2F32 &lhs, DN_V2F32 rhs)
{ {
lhs = lhs + rhs; lhs = lhs + rhs;
@ -682,10 +671,7 @@ DN_API DN_F32 DN_V2F32_Area(DN_V2F32 a)
DN_F32 result = a.w * a.h; DN_F32 result = a.w * a.h;
return result; return result;
} }
#endif // !defined(DN_NO_V2)
#if !defined(DN_NO_V3)
// NOTE: DN_V3 /////////////////////////////////////////////////////////////////////////////////////
DN_API bool operator!=(DN_V3F32 lhs, DN_V3F32 rhs) DN_API bool operator!=(DN_V3F32 lhs, DN_V3F32 rhs)
{ {
bool result = !(lhs == rhs); bool result = !(lhs == rhs);
@ -843,10 +829,7 @@ DN_API DN_V3F32 DN_V3_Normalise(DN_V3F32 a)
DN_V3F32 result = a / length; DN_V3F32 result = a / length;
return result; return result;
} }
#endif // !defined(DN_NO_V3)
#if !defined(DN_NO_V4)
// NOTE: DN_V4 /////////////////////////////////////////////////////////////////////////////////////
DN_API DN_V4F32 DN_V4F32_FromRGBU32(DN_U32 u32) DN_API DN_V4F32 DN_V4F32_FromRGBU32(DN_U32 u32)
{ {
DN_U8 r = (DN_U8)(((u32 << 8) & DN_V4_R_MASK_U32) >> 24); DN_U8 r = (DN_U8)(((u32 << 8) & DN_V4_R_MASK_U32) >> 24);
@ -979,10 +962,7 @@ DN_API DN_F32 DN_V4F32Dot(DN_V4F32 a, DN_V4F32 b)
DN_F32 result = (a.x * b.x) + (a.y * b.y) + (a.z * b.z) + (a.w * b.w); DN_F32 result = (a.x * b.x) + (a.y * b.y) + (a.z * b.z) + (a.w * b.w);
return result; return result;
} }
#endif // !defined(DN_NO_V4)
#if !defined(DN_NO_M4)
// NOTE: DN_M4 /////////////////////////////////////////////////////////////////////////////////////
DN_API DN_M4 DN_M4_Identity() DN_API DN_M4 DN_M4_Identity()
{ {
DN_M4 result = DN_M4 result =
@ -1231,9 +1211,7 @@ DN_API DN_Str8x256 DN_M4_ColumnMajorString(DN_M4 mat)
return result; return result;
} }
#endif // !defined(DN_M4)
// NOTE: DN_M2x3 ///////////////////////////////////////////////////////////////////////////////////
DN_API bool operator==(DN_M2x3 const &lhs, DN_M2x3 const &rhs) DN_API bool operator==(DN_M2x3 const &lhs, DN_M2x3 const &rhs)
{ {
bool result = DN_Memcmp(lhs.e, rhs.e, sizeof(lhs.e[0]) * DN_ArrayCountU(lhs.e)) == 0; bool result = DN_Memcmp(lhs.e, rhs.e, sizeof(lhs.e[0]) * DN_ArrayCountU(lhs.e)) == 0;
@ -1355,8 +1333,6 @@ DN_API DN_V2F32 DN_M2x3_MulV2(DN_M2x3 m1, DN_V2F32 v2)
return result; return result;
} }
#if !defined(DN_NO_RECT)
// NOTE: DN_Rect ///////////////////////////////////////////////////////////////////////////////////
DN_API bool operator==(const DN_Rect &lhs, const DN_Rect &rhs) DN_API bool operator==(const DN_Rect &lhs, const DN_Rect &rhs)
{ {
bool result = (lhs.pos == rhs.pos) && (lhs.size == rhs.size); bool result = (lhs.pos == rhs.pos) && (lhs.size == rhs.size);
@ -1561,9 +1537,6 @@ DN_API DN_V2F32 DN_Rect_BottomRight(DN_Rect rect)
DN_V2F32 result = DN_Rect_InterpolatedPoint(rect, DN_V2F32_From2N(1, 1)); DN_V2F32 result = DN_Rect_InterpolatedPoint(rect, DN_V2F32_From2N(1, 1));
return result; return result;
} }
#endif // !defined(DN_NO_RECT)
// NOTE: Raycast ///////////////////////////////////////////////////////////////////////////////////
DN_API DN_RaycastLineIntersectV2Result DN_Raycast_LineIntersectV2(DN_V2F32 origin_a, DN_V2F32 dir_a, DN_V2F32 origin_b, DN_V2F32 dir_b) DN_API DN_RaycastLineIntersectV2Result DN_Raycast_LineIntersectV2(DN_V2F32 origin_a, DN_V2F32 dir_a, DN_V2F32 origin_b, DN_V2F32 dir_b)
{ {
@ -1596,7 +1569,6 @@ DN_API DN_RaycastLineIntersectV2Result DN_Raycast_LineIntersectV2(DN_V2F32 origi
return result; return result;
} }
// NOTE: Other /////////////////////////////////////////////////////////////////////////////////////
DN_API DN_V2F32 DN_Lerp_V2F32(DN_V2F32 a, DN_F32 t, DN_V2F32 b) DN_API DN_V2F32 DN_Lerp_V2F32(DN_V2F32 a, DN_F32 t, DN_V2F32 b)
{ {
DN_V2F32 result = {}; DN_V2F32 result = {};

View File

@ -1,22 +1,29 @@
#if !defined(DN_MATH_H) #if !defined(DN_MATH_H)
#define DN_MATH_H #define DN_MATH_H
#include "../dn_base_inc.h"
DN_MSVC_WARNING_PUSH DN_MSVC_WARNING_PUSH
DN_MSVC_WARNING_DISABLE(4201) // warning C4201: nonstandard extension used: nameless struct/union DN_MSVC_WARNING_DISABLE(4201) // warning C4201: nonstandard extension used: nameless struct/union
#if !defined(DN_NO_V2)
// NOTE: DN_V2 /////////////////////////////////////////////////////////////////////////////////////
union DN_V2I32 union DN_V2I32
{ {
struct { int32_t x, y; }; struct { DN_I32 x, y; };
struct { int32_t w, h; }; struct { DN_I32 w, h; };
int32_t data[2]; DN_I32 data[2];
}; };
union DN_V2U16 union DN_V2U16
{ {
struct { uint16_t x, y; }; struct { DN_U16 x, y; };
struct { uint16_t w, h; }; struct { DN_U16 w, h; };
uint16_t data[2]; DN_U16 data[2];
};
union DN_V2U32
{
struct { DN_U32 x, y; };
struct { DN_U32 w, h; };
DN_U32 data[2];
}; };
union DN_V2F32 union DN_V2F32
@ -25,10 +32,7 @@ union DN_V2F32
struct { DN_F32 w, h; }; struct { DN_F32 w, h; };
DN_F32 data[2]; DN_F32 data[2];
}; };
#endif // !defined(DN_NO_V2)
#if !defined(DN_NO_V3)
// NOTE: DN_V3 /////////////////////////////////////////////////////////////////////////////////////
union DN_V3F32 union DN_V3F32
{ {
struct { DN_F32 x, y, z; }; struct { DN_F32 x, y, z; };
@ -36,10 +40,7 @@ union DN_V3F32
DN_F32 data[3]; DN_F32 data[3];
}; };
#endif // !defined(DN_NO_V3)
#if !defined(DN_NO_V4)
// NOTE: DN_V4 /////////////////////////////////////////////////////////////////////////////////////
union DN_V4F32 union DN_V4F32
{ {
struct { DN_F32 x, y, z, w; }; struct { DN_F32 x, y, z, w; };
@ -50,29 +51,19 @@ union DN_V4F32
#endif #endif
DN_F32 data[4]; DN_F32 data[4];
}; };
#endif // !defined(DN_NO_V4)
DN_MSVC_WARNING_POP DN_MSVC_WARNING_POP
#if !defined(DN_NO_M4)
// NOTE: DN_M4 /////////////////////////////////////////////////////////////////////////////////////
struct DN_M4 struct DN_M4
{ {
DN_F32 columns[4][4]; // Column major matrix DN_F32 columns[4][4]; // Column major matrix
}; };
#endif // !defined(DN_M4)
// NOTE: DN_M2x3 ///////////////////////////////////////////////////////////////////////////////////
union DN_M2x3 union DN_M2x3
{ {
DN_F32 e[6]; DN_F32 e[6];
DN_F32 row[2][3]; DN_F32 row[2][3];
}; };
// NOTE: DN_Rect ///////////////////////////////////////////////////////////////////////////////////
#if !defined(DN_NO_RECT)
#if defined(DN_NO_V2)
#error "Rectangles requires V2, DN_NO_V2 must not be defined"
#endif
struct DN_Rect struct DN_Rect
{ {
DN_V2F32 pos, size; DN_V2F32 pos, size;
@ -102,10 +93,7 @@ struct DN_RectCut
DN_Rect* rect; DN_Rect* rect;
DN_RectCutSide side; DN_RectCutSide side;
}; };
#endif // !defined(DN_NO_RECT)
// NOTE: Other /////////////////////////////////////////////////////////////////////////////////////
// NOTE: API
struct DN_RaycastLineIntersectV2Result struct DN_RaycastLineIntersectV2Result
{ {
bool hit; // True if there was an intersection, false if the lines are parallel bool hit; // True if there was an intersection, false if the lines are parallel
@ -113,13 +101,11 @@ struct DN_RaycastLineIntersectV2Result
DN_F32 t_b; // Distance along `dir_b` that the intersection occurred, e.g. `origin_b + (dir_b * t_b)` DN_F32 t_b; // Distance along `dir_b` that the intersection occurred, e.g. `origin_b + (dir_b * t_b)`
}; };
#if !defined(DN_NO_V2) #define DN_V2I32_Zero DN_Literal(DN_V2I32){{(int32_t)(0), (int32_t)(0)}}
// NOTE: DN_V2 ///////////////////////////////////////////////////////////////////////////////////// #define DN_V2I32_One DN_Literal(DN_V2I32){{(int32_t)(1), (int32_t)(1)}}
#define DN_V2I32_Zero DN_LITERAL(DN_V2I32){{(int32_t)(0), (int32_t)(0)}} #define DN_V2I32_From1N(x) DN_Literal(DN_V2I32){{(int32_t)(x), (int32_t)(x)}}
#define DN_V2I32_One DN_LITERAL(DN_V2I32){{(int32_t)(1), (int32_t)(1)}} #define DN_V2I32_From2N(x, y) DN_Literal(DN_V2I32){{(int32_t)(x), (int32_t)(y)}}
#define DN_V2I32_From1N(x) DN_LITERAL(DN_V2I32){{(int32_t)(x), (int32_t)(x)}} #define DN_V2I32_InitV2(xy) DN_Literal(DN_V2I32){{(int32_t)(xy).x, (int32_t)(xy).y}}
#define DN_V2I32_From2N(x, y) DN_LITERAL(DN_V2I32){{(int32_t)(x), (int32_t)(y)}}
#define DN_V2I32_InitV2(xy) DN_LITERAL(DN_V2I32){{(int32_t)(xy).x, (int32_t)(xy).y}}
DN_API bool operator!= (DN_V2I32 lhs, DN_V2I32 rhs); DN_API bool operator!= (DN_V2I32 lhs, DN_V2I32 rhs);
DN_API bool operator== (DN_V2I32 lhs, DN_V2I32 rhs); DN_API bool operator== (DN_V2I32 lhs, DN_V2I32 rhs);
@ -149,10 +135,10 @@ DN_API DN_V2I32 DN_V2I32_Min (DN_V2I32 a, DN
DN_API DN_V2I32 DN_V2I32_Max (DN_V2I32 a, DN_V2I32 b); DN_API DN_V2I32 DN_V2I32_Max (DN_V2I32 a, DN_V2I32 b);
DN_API DN_V2I32 DN_V2I32_Abs (DN_V2I32 a); DN_API DN_V2I32 DN_V2I32_Abs (DN_V2I32 a);
#define DN_V2U16_Zero DN_LITERAL(DN_V2U16){{(uint16_t)(0), (uint16_t)(0)}} #define DN_V2U16_Zero DN_Literal(DN_V2U16){{(uint16_t)(0), (uint16_t)(0)}}
#define DN_V2U16_One DN_LITERAL(DN_V2U16){{(uint16_t)(1), (uint16_t)(1)}} #define DN_V2U16_One DN_Literal(DN_V2U16){{(uint16_t)(1), (uint16_t)(1)}}
#define DN_V2U16_From1N(x) DN_LITERAL(DN_V2U16){{(uint16_t)(x), (uint16_t)(x)}} #define DN_V2U16_From1N(x) DN_Literal(DN_V2U16){{(uint16_t)(x), (uint16_t)(x)}}
#define DN_V2U16_From2N(x, y) DN_LITERAL(DN_V2U16){{(uint16_t)(x), (uint16_t)(y)}} #define DN_V2U16_From2N(x, y) DN_Literal(DN_V2U16){{(uint16_t)(x), (uint16_t)(y)}}
DN_API bool operator!= (DN_V2U16 lhs, DN_V2U16 rhs); DN_API bool operator!= (DN_V2U16 lhs, DN_V2U16 rhs);
DN_API bool operator== (DN_V2U16 lhs, DN_V2U16 rhs); DN_API bool operator== (DN_V2U16 lhs, DN_V2U16 rhs);
@ -177,11 +163,11 @@ DN_API DN_V2U16 & operator/= (DN_V2U16& lhs,
DN_API DN_V2U16 & operator-= (DN_V2U16& lhs, DN_V2U16 rhs); DN_API DN_V2U16 & operator-= (DN_V2U16& lhs, DN_V2U16 rhs);
DN_API DN_V2U16 & operator+= (DN_V2U16& lhs, DN_V2U16 rhs); DN_API DN_V2U16 & operator+= (DN_V2U16& lhs, DN_V2U16 rhs);
#define DN_V2F32_Zero DN_LITERAL(DN_V2F32){{(DN_F32)(0), (DN_F32)(0)}} #define DN_V2F32_Zero DN_Literal(DN_V2F32){{(DN_F32)(0), (DN_F32)(0)}}
#define DN_V2F32_One DN_LITERAL(DN_V2F32){{(DN_F32)(1), (DN_F32)(1)}} #define DN_V2F32_One DN_Literal(DN_V2F32){{(DN_F32)(1), (DN_F32)(1)}}
#define DN_V2F32_From1N(x) DN_LITERAL(DN_V2F32){{(DN_F32)(x), (DN_F32)(x)}} #define DN_V2F32_From1N(x) DN_Literal(DN_V2F32){{(DN_F32)(x), (DN_F32)(x)}}
#define DN_V2F32_From2N(x, y) DN_LITERAL(DN_V2F32){{(DN_F32)(x), (DN_F32)(y)}} #define DN_V2F32_From2N(x, y) DN_Literal(DN_V2F32){{(DN_F32)(x), (DN_F32)(y)}}
#define DN_V2F32_FromV2I32(xy) DN_LITERAL(DN_V2F32){{(DN_F32)(xy).x, (DN_F32)(xy).y}} #define DN_V2F32_FromV2I32(xy) DN_Literal(DN_V2F32){{(DN_F32)(xy).x, (DN_F32)(xy).y}}
DN_API bool operator!= (DN_V2F32 lhs, DN_V2F32 rhs); DN_API bool operator!= (DN_V2F32 lhs, DN_V2F32 rhs);
DN_API bool operator== (DN_V2F32 lhs, DN_V2F32 rhs); DN_API bool operator== (DN_V2F32 lhs, DN_V2F32 rhs);
@ -244,12 +230,10 @@ DN_API DN_V2F32 DN_V2F32_Normalise (DN_V2F32 a);
DN_API DN_V2F32 DN_V2F32_Perpendicular (DN_V2F32 a); DN_API DN_V2F32 DN_V2F32_Perpendicular (DN_V2F32 a);
DN_API DN_V2F32 DN_V2F32_Reflect (DN_V2F32 in, DN_V2F32 surface); DN_API DN_V2F32 DN_V2F32_Reflect (DN_V2F32 in, DN_V2F32 surface);
DN_API DN_F32 DN_V2F32_Area (DN_V2F32 a); DN_API DN_F32 DN_V2F32_Area (DN_V2F32 a);
#endif // !defined(DN_NO_V2)
#if !defined(DN_NO_V3) #define DN_V3F32_From1N(x) DN_Literal(DN_V3F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}}
// NOTE: DN_V3 ///////////////////////////////////////////////////////////////////////////////////// #define DN_V3F32_From3N(x, y, z) DN_Literal(DN_V3F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z)}}
#define DN_V3F32_From1N(x) DN_LITERAL(DN_V3F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}} #define DN_V3F32_FromV2F32And1N(xy, z) DN_Literal(DN_V3F32){{(DN_F32)(xy.x), (DN_F32)(xy.y), (DN_F32)(z)}}
#define DN_V3F32_From3N(x, y, z) DN_LITERAL(DN_V3F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z)}}
#define DN_V3F32_FromV2F32And1N(xy, z) DN_LITERAL(DN_V3F32){{(DN_F32)(xy.x), (DN_F32)(xy.y), (DN_F32)(z)}}
DN_API bool operator== (DN_V3F32 lhs, DN_V3F32 rhs); DN_API bool operator== (DN_V3F32 lhs, DN_V3F32 rhs);
DN_API bool operator!= (DN_V3F32 lhs, DN_V3F32 rhs); DN_API bool operator!= (DN_V3F32 lhs, DN_V3F32 rhs);
@ -277,19 +261,17 @@ DN_API DN_V3F32 & operator+= (DN_V3F32 &lhs,
DN_API DN_F32 DN_V3F32_LengthSq (DN_V3F32 a); DN_API DN_F32 DN_V3F32_LengthSq (DN_V3F32 a);
DN_API DN_F32 DN_V3F32_Length (DN_V3F32 a); DN_API DN_F32 DN_V3F32_Length (DN_V3F32 a);
DN_API DN_V3F32 DN_V3F32_Normalise (DN_V3F32 a); DN_API DN_V3F32 DN_V3F32_Normalise (DN_V3F32 a);
#endif // !defined(DN_NO_V3)
#if !defined(DN_NO_V4)
DN_U32 const DN_V4_R_MASK_U32 = 0xFF000000; DN_U32 const DN_V4_R_MASK_U32 = 0xFF000000;
DN_U32 const DN_V4_G_MASK_U32 = 0x00FF0000; DN_U32 const DN_V4_G_MASK_U32 = 0x00FF0000;
DN_U32 const DN_V4_B_MASK_U32 = 0x0000FF00; DN_U32 const DN_V4_B_MASK_U32 = 0x0000FF00;
DN_U32 const DN_V4_A_MASK_U32 = 0x000000FF; DN_U32 const DN_V4_A_MASK_U32 = 0x000000FF;
// NOTE: DN_V4 ///////////////////////////////////////////////////////////////////////////////////// #define DN_V4F32_From1N(x) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}}
#define DN_V4F32_From1N(x) DN_LITERAL(DN_V4F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}} #define DN_V4F32_From4N(x, y, z, w) DN_Literal(DN_V4F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z), (DN_F32)(w)}}
#define DN_V4F32_From4N(x, y, z, w) DN_LITERAL(DN_V4F32){{(DN_F32)(x), (DN_F32)(y), (DN_F32)(z), (DN_F32)(w)}} #define DN_V4F32_FromV3And1N(xyz, w) DN_Literal(DN_V4F32){{xyz.x, xyz.y, xyz.z, w}}
#define DN_V4F32_FromV3And1N(xyz, w) DN_LITERAL(DN_V4F32){{xyz.x, xyz.y, xyz.z, w}} #define DN_V4F32_FromRGBAU8(r, g, b, a) DN_Literal(DN_V4F32){{r / 255.f, g / 255.f, b / 255.f, a / 255.f}}
#define DN_V4F32_FromRGBAU8(r, g, b, a) DN_LITERAL(DN_V4F32){{r / 255.f, g / 255.f, b / 255.f, a / 255.f}} #define DN_V4F32_FromRGBU8(r, g, b) DN_Literal(DN_V4F32){{r / 255.f, g / 255.f, b / 255.f, 1.f}}
#define DN_V4F32_FromRGBU8(r, g, b) DN_LITERAL(DN_V4F32){{r / 255.f, g / 255.f, b / 255.f, 1.f}}
DN_API DN_V4F32 DN_V4F32_FromRGBU32(DN_U32 u32); DN_API DN_V4F32 DN_V4F32_FromRGBU32(DN_U32 u32);
DN_API DN_V4F32 DN_V4F32_FromRGBAU32(DN_U32 u32); DN_API DN_V4F32 DN_V4F32_FromRGBAU32(DN_U32 u32);
#define DN_V4F32_FromV4Alpha(v4, alpha) DN_V4F32_FromV3And1N(v4.xyz, alpha) #define DN_V4F32_FromV4Alpha(v4, alpha) DN_V4F32_FromV3And1N(v4.xyz, alpha)
@ -311,9 +293,7 @@ DN_API DN_V4F32 & operator*= (DN_V4F32 &lhs,
DN_API DN_V4F32 & operator-= (DN_V4F32 &lhs, DN_V4F32 rhs); DN_API DN_V4F32 & operator-= (DN_V4F32 &lhs, DN_V4F32 rhs);
DN_API DN_V4F32 & operator+= (DN_V4F32 &lhs, DN_V4F32 rhs); DN_API DN_V4F32 & operator+= (DN_V4F32 &lhs, DN_V4F32 rhs);
DN_API DN_F32 DN_V4F32_Dot (DN_V4F32 a, DN_V4F32 b); DN_API DN_F32 DN_V4F32_Dot (DN_V4F32 a, DN_V4F32 b);
#endif // !defined(DN_NO_V4)
#if !defined(DN_NO_M4)
// NOTE: DN_M4 /////////////////////////////////////////////////////////////////////////////////////
DN_API DN_M4 DN_M4_Identity (); DN_API DN_M4 DN_M4_Identity ();
DN_API DN_M4 DN_M4_ScaleF (DN_F32 x, DN_F32 y, DN_F32 z); DN_API DN_M4 DN_M4_ScaleF (DN_F32 x, DN_F32 y, DN_F32 z);
DN_API DN_M4 DN_M4_Scale (DN_V3F32 xyz); DN_API DN_M4 DN_M4_Scale (DN_V3F32 xyz);
@ -332,8 +312,7 @@ DN_API DN_M4 DN_M4_SubF (DN_M4 lhs, DN_
DN_API DN_M4 DN_M4_MulF (DN_M4 lhs, DN_F32 rhs); DN_API DN_M4 DN_M4_MulF (DN_M4 lhs, DN_F32 rhs);
DN_API DN_M4 DN_M4_DivF (DN_M4 lhs, DN_F32 rhs); DN_API DN_M4 DN_M4_DivF (DN_M4 lhs, DN_F32 rhs);
DN_API DN_Str8x256 DN_M4_ColumnMajorString (DN_M4 mat); DN_API DN_Str8x256 DN_M4_ColumnMajorString (DN_M4 mat);
#endif // !defined(DN_NO_M4)
// NOTE: DN_M2x3 ///////////////////////////////////////////////////////////////////////////////////
DN_API bool operator== (DN_M2x3 const &lhs, DN_M2x3 const &rhs); DN_API bool operator== (DN_M2x3 const &lhs, DN_M2x3 const &rhs);
DN_API bool operator!= (DN_M2x3 const &lhs, DN_M2x3 const &rhs); DN_API bool operator!= (DN_M2x3 const &lhs, DN_M2x3 const &rhs);
DN_API DN_M2x3 DN_M2x3_Identity (); DN_API DN_M2x3 DN_M2x3_Identity ();
@ -343,10 +322,9 @@ DN_API DN_M2x3 DN_M2x3_Rotate (DN_F32 radians
DN_API DN_M2x3 DN_M2x3_Mul (DN_M2x3 m1, DN_M2x3 m2); DN_API DN_M2x3 DN_M2x3_Mul (DN_M2x3 m1, DN_M2x3 m2);
DN_API DN_V2F32 DN_M2x3_Mul2F32 (DN_M2x3 m1, DN_F32 x, DN_F32 y); DN_API DN_V2F32 DN_M2x3_Mul2F32 (DN_M2x3 m1, DN_F32 x, DN_F32 y);
DN_API DN_V2F32 DN_M2x3_MulV2 (DN_M2x3 m1, DN_V2F32 v2); DN_API DN_V2F32 DN_M2x3_MulV2 (DN_M2x3 m1, DN_V2F32 v2);
#if !defined(DN_NO_RECT)
// NOTE: DN_Rect /////////////////////////////////////////////////////////////////////////////////// #define DN_Rect_From2V2(pos, size) DN_Literal(DN_Rect){(pos), (size)}
#define DN_Rect_From2V2(pos, size) DN_LITERAL(DN_Rect){(pos), (size)} #define DN_Rect_From4N(x, y, w, h) DN_Literal(DN_Rect){DN_Literal(DN_V2F32){{x, y}}, DN_Literal(DN_V2F32){{w, h}}}
#define DN_Rect_From4N(x, y, w, h) DN_LITERAL(DN_Rect){DN_LITERAL(DN_V2F32){{x, y}}, DN_LITERAL(DN_V2F32){{w, h}}}
DN_API bool operator== (const DN_Rect& lhs, const DN_Rect& rhs); DN_API bool operator== (const DN_Rect& lhs, const DN_Rect& rhs);
DN_API DN_V2F32 DN_Rect_Center (DN_Rect rect); DN_API DN_V2F32 DN_Rect_Center (DN_Rect rect);
@ -381,13 +359,12 @@ DN_API DN_Rect DN_Rect_CutBottomClip (DN_Rect *rect,
#define DN_Rect_CutBottomNoClip(rect, amount) DN_Rect_CutBottomClip(rect, amount, DN_RectCutClip_No) #define DN_Rect_CutBottomNoClip(rect, amount) DN_Rect_CutBottomClip(rect, amount, DN_RectCutClip_No)
DN_API DN_Rect DN_RectCut_Cut (DN_RectCut rect_cut, DN_V2F32 size, DN_RectCutClip clip); DN_API DN_Rect DN_RectCut_Cut (DN_RectCut rect_cut, DN_V2F32 size, DN_RectCutClip clip);
#define DN_RectCut_Init(rect, side) DN_LITERAL(DN_RectCut){rect, side} #define DN_RectCut_Init(rect, side) DN_Literal(DN_RectCut){rect, side}
#define DN_RectCut_Left(rect) DN_LITERAL(DN_RectCut){rect, DN_RectCutSide_Left} #define DN_RectCut_Left(rect) DN_Literal(DN_RectCut){rect, DN_RectCutSide_Left}
#define DN_RectCut_Right(rect) DN_LITERAL(DN_RectCut){rect, DN_RectCutSide_Right} #define DN_RectCut_Right(rect) DN_Literal(DN_RectCut){rect, DN_RectCutSide_Right}
#define DN_RectCut_Top(rect) DN_LITERAL(DN_RectCut){rect, DN_RectCutSide_Top} #define DN_RectCut_Top(rect) DN_Literal(DN_RectCut){rect, DN_RectCutSide_Top}
#define DN_RectCut_Bottom(rect) DN_LITERAL(DN_RectCut){rect, DN_RectCutSide_Bottom} #define DN_RectCut_Bottom(rect) DN_Literal(DN_RectCut){rect, DN_RectCutSide_Bottom}
#endif // !defined(DN_NO_RECT)
// NOTE: Other /////////////////////////////////////////////////////////////////////////////////////
DN_API DN_RaycastLineIntersectV2Result DN_Raycast_LineIntersectV2(DN_V2F32 origin_a, DN_V2F32 dir_a, DN_V2F32 origin_b, DN_V2F32 dir_b); DN_API DN_RaycastLineIntersectV2Result DN_Raycast_LineIntersectV2(DN_V2F32 origin_a, DN_V2F32 dir_a, DN_V2F32 origin_b, DN_V2F32 dir_b);
DN_API DN_V2F32 DN_Lerp_V2F32 (DN_V2F32 a, DN_F32 t, DN_V2F32 b); DN_API DN_V2F32 DN_Lerp_V2F32 (DN_V2F32 a, DN_F32 t, DN_V2F32 b);
DN_API DN_F32 DN_Lerp_F32 (DN_F32 a, DN_F32 t, DN_F32 b); DN_API DN_F32 DN_Lerp_F32 (DN_F32 a, DN_F32 t, DN_F32 b);

View File

@ -1814,7 +1814,7 @@ static DN_UTCore DN_Tests_OS()
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str8 os_result = DN_OS_EXEDir(tmem.arena); DN_Str8 os_result = DN_OS_EXEDir(tmem.arena);
DN_UT_Assert(&result, DN_Str8_HasData(os_result)); DN_UT_Assert(&result, DN_Str8_HasData(os_result));
DN_UT_AssertF(&result, DN_OS_DirExists(os_result), "result(%zu): %.*s", os_result.size, DN_STR_FMT(os_result)); DN_UT_AssertF(&result, DN_OS_PathIsDir(os_result), "result(%zu): %.*s", os_result.size, DN_STR_FMT(os_result));
} }
for (DN_UT_Test(&result, "DN_OS_PerfCounterNow")) { for (DN_UT_Test(&result, "DN_OS_PerfCounterNow")) {
@ -1844,11 +1844,11 @@ static DN_UTCore DN_Tests_OS()
DN_UT_LogF(&result, "\nDN_OS Filesystem\n"); DN_UT_LogF(&result, "\nDN_OS Filesystem\n");
{ {
for (DN_UT_Test(&result, "Make directory recursive \"abcd/efgh\"")) { for (DN_UT_Test(&result, "Make directory recursive \"abcd/efgh\"")) {
DN_UT_AssertF(&result, DN_OS_MakeDir(DN_STR8("abcd/efgh")), "Failed to make directory"); DN_UT_AssertF(&result, DN_OS_PathMakeDir(DN_STR8("abcd/efgh")), "Failed to make directory");
DN_UT_AssertF(&result, DN_OS_DirExists(DN_STR8("abcd")), "Directory was not made"); DN_UT_AssertF(&result, DN_OS_PathIsDir(DN_STR8("abcd")), "Directory was not made");
DN_UT_AssertF(&result, DN_OS_DirExists(DN_STR8("abcd/efgh")), "Subdirectory was not made"); DN_UT_AssertF(&result, DN_OS_PathIsDir(DN_STR8("abcd/efgh")), "Subdirectory was not made");
DN_UT_AssertF(&result, DN_OS_FileExists(DN_STR8("abcd")) == false, "This function should only return true for files"); DN_UT_AssertF(&result, DN_OS_PathIsFile(DN_STR8("abcd")) == false, "This function should only return true for files");
DN_UT_AssertF(&result, DN_OS_FileExists(DN_STR8("abcd/efgh")) == false, "This function should only return true for files"); DN_UT_AssertF(&result, DN_OS_PathIsFile(DN_STR8("abcd/efgh")) == false, "This function should only return true for files");
DN_UT_AssertF(&result, DN_OS_PathDelete(DN_STR8("abcd/efgh")), "Failed to delete directory"); DN_UT_AssertF(&result, DN_OS_PathDelete(DN_STR8("abcd/efgh")), "Failed to delete directory");
DN_UT_AssertF(&result, DN_OS_PathDelete(DN_STR8("abcd")), "Failed to cleanup directory"); DN_UT_AssertF(&result, DN_OS_PathDelete(DN_STR8("abcd")), "Failed to cleanup directory");
} }
@ -1856,29 +1856,29 @@ static DN_UTCore DN_Tests_OS()
for (DN_UT_Test(&result, "File write, read, copy, move and delete")) { for (DN_UT_Test(&result, "File write, read, copy, move and delete")) {
// NOTE: Write step // NOTE: Write step
DN_Str8 const SRC_FILE = DN_STR8("dn_result_file"); DN_Str8 const SRC_FILE = DN_STR8("dn_result_file");
DN_B32 write_result = DN_OS_WriteAll(SRC_FILE, DN_STR8("1234"), nullptr); DN_B32 write_result = DN_OS_FileWriteAll(SRC_FILE, DN_STR8("1234"), nullptr);
DN_UT_Assert(&result, write_result); DN_UT_Assert(&result, write_result);
DN_UT_Assert(&result, DN_OS_FileExists(SRC_FILE)); DN_UT_Assert(&result, DN_OS_PathIsFile(SRC_FILE));
// NOTE: Read step // NOTE: Read step
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str8 read_file = DN_OS_ReadAll(tmem.arena, SRC_FILE, nullptr); DN_Str8 read_file = DN_OS_FileReadAllArena(tmem.arena, SRC_FILE, nullptr);
DN_UT_AssertF(&result, DN_Str8_HasData(read_file), "Failed to load file"); DN_UT_AssertF(&result, DN_Str8_HasData(read_file), "Failed to load file");
DN_UT_AssertF(&result, read_file.size == 4, "File read wrong amount of bytes (%zu)", read_file.size); DN_UT_AssertF(&result, read_file.size == 4, "File read wrong amount of bytes (%zu)", read_file.size);
DN_UT_AssertF(&result, DN_Str8_Eq(read_file, DN_STR8("1234")), "Read %zu bytes instead of the expected 4: '%.*s'", read_file.size, DN_STR_FMT(read_file)); DN_UT_AssertF(&result, DN_Str8_Eq(read_file, DN_STR8("1234")), "Read %zu bytes instead of the expected 4: '%.*s'", read_file.size, DN_STR_FMT(read_file));
// NOTE: Copy step // NOTE: Copy step
DN_Str8 const COPY_FILE = DN_STR8("dn_result_file_copy"); DN_Str8 const COPY_FILE = DN_STR8("dn_result_file_copy");
DN_B32 copy_result = DN_OS_CopyFile(SRC_FILE, COPY_FILE, true /*overwrite*/, nullptr); DN_B32 copy_result = DN_OS_FileCopy(SRC_FILE, COPY_FILE, true /*overwrite*/, nullptr);
DN_UT_Assert(&result, copy_result); DN_UT_Assert(&result, copy_result);
DN_UT_Assert(&result, DN_OS_FileExists(COPY_FILE)); DN_UT_Assert(&result, DN_OS_PathIsFile(COPY_FILE));
// NOTE: Move step // NOTE: Move step
DN_Str8 const MOVE_FILE = DN_STR8("dn_result_file_move"); DN_Str8 const MOVE_FILE = DN_STR8("dn_result_file_move");
DN_B32 move_result = DN_OS_MoveFile(COPY_FILE, MOVE_FILE, true /*overwrite*/, nullptr); DN_B32 move_result = DN_OS_FileMove(COPY_FILE, MOVE_FILE, true /*overwrite*/, nullptr);
DN_UT_Assert(&result, move_result); DN_UT_Assert(&result, move_result);
DN_UT_Assert(&result, DN_OS_FileExists(MOVE_FILE)); DN_UT_Assert(&result, DN_OS_PathIsFile(MOVE_FILE));
DN_UT_AssertF(&result, DN_OS_FileExists(COPY_FILE) == false, "Moving a file should remove the original"); DN_UT_AssertF(&result, DN_OS_PathIsFile(COPY_FILE) == false, "Moving a file should remove the original");
// NOTE: Delete step // NOTE: Delete step
DN_B32 delete_src_file = DN_OS_PathDelete(SRC_FILE); DN_B32 delete_src_file = DN_OS_PathDelete(SRC_FILE);

View File

@ -1,5 +1,8 @@
#define DN_OS_CPP #define DN_OS_CPP
#include "../dn_base_inc.h"
#include "../dn_os_inc.h"
#if defined(DN_PLATFORM_POSIX) #if defined(DN_PLATFORM_POSIX)
#include <sys/sysinfo.h> // get_nprocs #include <sys/sysinfo.h> // get_nprocs
#include <unistd.h> // getpagesize #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; return result;
} }
#if !defined(DN_NO_OS_FILE_API) DN_API bool DN_OS_PathIsOlderThan(DN_Str8 path, DN_Str8 check_against)
// NOTE: DN_OSPathInfo/File ////////////////////////////////////////////////////////////////////////
DN_API bool DN_OS_FileIsOlderThan(DN_Str8 file, 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); 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; bool result = !file_info.exists || file_info.last_write_time_in_s < check_against_info.last_write_time_in_s;
return result; return result;
@ -445,44 +446,69 @@ DN_API bool DN_OS_FileWriteF(DN_OSFile *file, DN_OSErrSink *error, DN_FMT_ATTRIB
return result; return result;
} }
// NOTE: R/W Entire 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_ReadAll(DN_Arena *arena, DN_Str8 path, DN_OSErrSink *error)
{ {
DN_Str8 result = {}; // NOTE: Query file size
if (!arena) DN_Str8 result = {};
return result;
// NOTE: Query file size + allocate buffer /////////////////////////////////////////////////////
DN_OSPathInfo path_info = DN_OS_PathInfo(path); DN_OSPathInfo path_info = DN_OS_PathInfo(path);
if (!path_info.exists) { 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; return result;
} }
DN_ArenaTempMem temp_mem = DN_Arena_TempMemBegin(arena); // NOTE: Allocate
result = DN_Str8_Alloc(arena, path_info.size, DN_ZeroMem_No); DN_ArenaTempMem arena_tmp = {};
if (!DN_Str8_HasData(result)) { if (alloc_type == DN_Allocator_Arena) {
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); DN_Arena *arena = DN_CAST(DN_Arena *) allocator;
DN_Str8 buffer_size_str8 = DN_CVT_BytesStr8FromU64AutoTLS(path_info.size); arena_tmp = DN_Arena_TempMemBegin(arena);
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)); result = DN_Str8_Alloc(arena, path_info.size, DN_ZeroMem_No);
DN_Arena_TempMemEnd(temp_mem); } else {
result = {}; 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; return result;
} }
// NOTE: Read the file from disk /////////////////////////////////////////////////////////////// // NOTE: Read all
DN_OSFile file = DN_OS_FileOpen(path, DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_Read, error); 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, error); DN_OSFileRead read = DN_OS_FileRead(&file, result.data, result.size, err);
if (file.error || !read.success) { 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 = {}; result = {};
} }
DN_OS_FileClose(&file);
DN_OS_FileClose(&file);
return result; 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); DN_OSFile file = DN_OS_FileOpen(path, DN_OSFileOpen_CreateAlways, DN_OSFileAccess_Write, error);
bool result = DN_OS_FileWrite(&file, buffer, 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; 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_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str8 buffer = DN_Str8_FromFV(tmem.arena, fmt, args); DN_Str8 buffer = DN_Str8_FromFV(tmem.arena, fmt, args);
bool result = DN_OS_WriteAll(file_path, buffer, error); bool result = DN_OS_FileWriteAll(file_path, buffer, error);
return result; 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_list args;
va_start(args, fmt); 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); va_end(args);
return result; 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_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str8 tmp_path = DN_Str8_FromF(tmem.arena, "%.*s.tmp", DN_STR_FMT(path)); 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; return false;
if (!DN_OS_CopyFile(tmp_path, path, true /*overwrite*/, error)) if (!DN_OS_FileCopy(tmp_path, path, true /*overwrite*/, error))
return false; return false;
if (!DN_OS_PathDelete(tmp_path)) if (!DN_OS_PathDelete(tmp_path))
return false; return false;
return true; 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_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str8 buffer = DN_Str8_FromFV(tmem.arena, fmt, args); 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; 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_list args;
va_start(args, fmt); va_start(args, fmt);
bool result = DN_OS_WriteAllSafeFV(path, error, fmt, args); bool result = DN_OS_FileWriteAllSafeFV(path, error, fmt, args);
return result; 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) DN_API bool DN_OS_PathAddRef(DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path)
{ {
if (!arena || !fs_path || !DN_Str8_HasData(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; 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_API bool DN_OS_PathAdd(DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path)
{ {
DN_Str8 copy = DN_Str8_FromStr8(arena, path); DN_Str8 copy = DN_Str8_FromStr8(arena, path);

View File

@ -1,6 +1,9 @@
#if !defined(DN_OS_H) #if !defined(DN_OS_H)
#define DN_OS_H #define DN_OS_H
#include "../dn_base_inc.h"
#include "../dn_os_inc.h"
#include <new> // operator new #include <new> // operator new
#if !defined(DN_OS_WIN32) || defined(DN_OS_WIN32_USE_PTHREADS) #if !defined(DN_OS_WIN32) || defined(DN_OS_WIN32_USE_PTHREADS)
@ -302,94 +305,87 @@ struct DN_OSDiskSpace
DN_U64 size; DN_U64 size;
}; };
DN_API void DN_OS_Init (DN_OSCore *os, DN_OSInitArgs *args); 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_EmitLogsWithOSPrintFunctions (DN_OSCore *os);
DN_API void DN_OS_DumpThreadContextArenaStat (DN_Str8 file_path); 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 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 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_MemDecommit(void *ptr, DN_USize size); DN_API void DN_OS_MemRelease (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 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_MemAlloc (DN_USize size, DN_ZeroMem zero_mem); DN_API void DN_OS_MemDealloc (void *ptr);
DN_API void DN_OS_MemDealloc (void *ptr);
// NOTE: DN_OSDate ///////////////////////////////////////////////////////////////////////////////// DN_API DN_OSDateTime DN_OS_DateLocalTimeNow ();
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_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_OSDateTimeStr8 DN_OS_DateLocalTimeStr8 (DN_OSDateTime time, char date_separator = '-', char hms_separator = ':'); DN_API DN_U64 DN_OS_DateUnixTimeNs ();
DN_API DN_U64 DN_OS_DateUnixTimeNs (); #define DN_OS_DateUnixTimeUs() (DN_OS_DateUnixTimeNs() / 1000)
#define DN_OS_DateUnixTimeUs() (DN_OS_DateUnixTimeNs() / 1000) #define DN_OS_DateUnixTimeMs() (DN_OS_DateUnixTimeNs() / (1000 * 1000))
#define DN_OS_DateUnixTimeMs() (DN_OS_DateUnixTimeNs() / (1000 * 1000)) #define DN_OS_DateUnixTimeS() (DN_OS_DateUnixTimeNs() / (1000 * 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_OSDateTime DN_OS_DateUnixTimeSToDate (DN_U64 time); DN_API DN_U64 DN_OS_DateLocalToUnixTimeS (DN_OSDateTime date);
DN_API DN_U64 DN_OS_DateLocalToUnixTimeS(DN_OSDateTime date); DN_API DN_U64 DN_OS_DateToUnixTimeS (DN_OSDateTime date);
DN_API DN_U64 DN_OS_DateToUnixTimeS (DN_OSDateTime date); DN_API bool DN_OS_DateIsValid (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 void DN_OS_GenBytesSecure (void *buffer, DN_U32 size); DN_API bool DN_OS_SetEnvVar (DN_Str8 name, DN_Str8 value);
DN_API bool DN_OS_SetEnvVar (DN_Str8 name, DN_Str8 value); DN_API DN_OSDiskSpace DN_OS_DiskSpace (DN_Str8 path);
DN_API DN_OSDiskSpace DN_OS_DiskSpace (DN_Str8 path); DN_API DN_Str8 DN_OS_EXEPath (DN_Arena *arena);
DN_API DN_Str8 DN_OS_EXEPath (DN_Arena *arena); DN_API DN_Str8 DN_OS_EXEDir (DN_Arena *arena);
DN_API DN_Str8 DN_OS_EXEDir (DN_Arena *arena); #define DN_OS_EXEDirFromTLS() DN_OS_EXEDir(DN_OS_TLSTopArena())
#define DN_OS_EXEDirFromTLS() DN_OS_EXEDir(DN_OS_TLSTopArena()) DN_API void DN_OS_SleepMs (DN_UInt milliseconds);
DN_API void DN_OS_SleepMs (DN_UInt milliseconds);
// NOTE: Counters ////////////////////////////////////////////////////////////////////////////////// DN_API DN_U64 DN_OS_PerfCounterNow ();
DN_API DN_U64 DN_OS_PerfCounterNow (); DN_API DN_U64 DN_OS_PerfCounterFrequency ();
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_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_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_PerfCounterUs (DN_U64 begin, uint64_t end); DN_API DN_F64 DN_OS_PerfCounterNs (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 DN_OSTimer DN_OS_TimerBegin (); DN_API void DN_OS_TimerEnd (DN_OSTimer *timer);
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_TimerS (DN_OSTimer timer); DN_API DN_F64 DN_OS_TimerMs (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_TimerUs (DN_OSTimer timer); DN_API DN_F64 DN_OS_TimerNs (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);
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);
// NOTE: R/W Stream API //////////////////////////////////////////////////////////////////////////// DN_API bool DN_OS_FileCopy (DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *err);
DN_API DN_OSFile DN_OS_FileOpen (DN_Str8 path, DN_OSFileOpen open_mode, DN_OSFileAccess access, DN_OSErrSink *err); DN_API bool DN_OS_FileMove (DN_Str8 src, DN_Str8 dest, bool overwrite, 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);
// NOTE: R/W Entire File /////////////////////////////////////////////////////////////////////////// DN_API DN_OSFile DN_OS_FileOpen (DN_Str8 path, DN_OSFileOpen open_mode, DN_OSFileAccess access, DN_OSErrSink *err);
DN_API DN_Str8 DN_OS_ReadAll (DN_Arena *arena, DN_Str8 path, DN_OSErrSink *err); DN_API DN_OSFileRead DN_OS_FileRead (DN_OSFile *file, void *buffer, DN_USize size, DN_OSErrSink *err);
#define DN_OS_ReadAllFromTLS(...) DN_OS_ReadAll(DN_OS_TLSTopArena(), ##__VA_ARGS__) DN_API bool DN_OS_FileWritePtr (DN_OSFile *file, void const *data, DN_USize size, DN_OSErrSink *err);
DN_API bool DN_OS_WriteAll (DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *err); DN_API bool DN_OS_FileWrite (DN_OSFile *file, 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_FileWriteFV (DN_OSFile *file, 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_FileWriteF (DN_OSFile *file, 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_FileFlush (DN_OSFile *file, 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 void DN_OS_FileClose (DN_OSFile *file);
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_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); 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__) DN_API bool DN_OS_PathAddRefTLS (DN_OSPath *fs_path, DN_Str8 path);
#define DN_OS_PathAddRefFromFrame(...) DN_OS_PathAddRef(DN_OS_TLSFrameArena(), ##__VA_ARGS__) 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); 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_PathAddFromTLS(...) DN_OS_PathAdd(DN_OS_TLSTopArena(), ##__VA_ARGS__)
#define DN_OS_PathAddFromFrame(...) DN_OS_PathAdd(DN_OS_TLSFrameArena(), ##__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_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) #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 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_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_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_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_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);
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())
#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 DN_OSSemaphore DN_OS_SemaphoreInit (DN_U32 initial_count);
DN_API bool DN_OS_SemaphoreIsValid (DN_OSSemaphore *semaphore); DN_API bool DN_OS_SemaphoreIsValid (DN_OSSemaphore *semaphore);
DN_API void DN_OS_SemaphoreDeinit (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 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_OSSemaphoreWaitResult DN_OS_SemaphoreWait (DN_OSSemaphore *semaphore, DN_U32 timeout_ms);
DN_API DN_OSMutex DN_OS_MutexInit (); DN_API DN_OSMutex DN_OS_MutexInit ();
DN_API void DN_OS_MutexDeinit(DN_OSMutex *mutex); DN_API void DN_OS_MutexDeinit (DN_OSMutex *mutex);
DN_API void DN_OS_MutexLock (DN_OSMutex *mutex); DN_API void DN_OS_MutexLock (DN_OSMutex *mutex);
DN_API void DN_OS_MutexUnlock(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)) #define DN_OS_MutexScope (mutex) DN_DeferLoop(DN_OS_MutexLock(mutex), DN_OS_MutexUnlock(mutex))
DN_API DN_OSConditionVariable DN_OS_ConditionVariableInit (); DN_API DN_OSConditionVariable DN_OS_ConditionVariableInit ();
DN_API void DN_OS_ConditionVariableDeinit (DN_OSConditionVariable *cv); 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_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 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_ConditionVariableSignal (DN_OSConditionVariable *cv);
DN_API void DN_OS_ConditionVariableBroadcast(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 bool DN_OS_ThreadInit (DN_OSThread *thread, DN_OSThreadFunc *func, void *user_context);
DN_API void DN_OS_ThreadDeinit(DN_OSThread *thread); DN_API void DN_OS_ThreadDeinit (DN_OSThread *thread);
DN_API DN_U32 DN_OS_ThreadID (); DN_API DN_U32 DN_OS_ThreadID ();
DN_API void DN_OS_ThreadSetName(DN_Str8 name); 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_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_HttpRequestWait (DN_OSHttpResponse *response);
DN_API void DN_OS_HttpRequestFree (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 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) #endif // !defined(DN_OS_H)

View File

@ -1,7 +1,7 @@
#if !defined(DN_OS_ALLOCATOR_H) #if !defined(DN_OS_ALLOCATOR_H)
#define 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); DN_API DN_Arena DN_Arena_FromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags);
#endif // !defined(DN_OS_ALLOCATOR_H) #endif // !defined(DN_OS_ALLOCATOR_H)

View File

@ -196,7 +196,7 @@ DN_API DN_OSDiskSpace DN_OS_DiskSpace(DN_Str8 path)
{ {
DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr); DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr);
DN_OSDiskSpace result = {}; 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 = {}; struct statvfs info = {};
if (statvfs(path_z_terminated.data, &info) != 0) if (statvfs(path_z_terminated.data, &info) != 0)
@ -297,52 +297,7 @@ DN_API DN_U64 DN_OS_PerfCounterNow()
return result; return result;
} }
#if !defined(DN_NO_OS_FILE_API) DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *error)
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)
{ {
bool result = false; bool result = false;
#if defined(DN_PLATFORM_EMSCRIPTEN) #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; 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 // See: https://github.com/gingerBill/gb/blob/master/gb.h
bool result = false; 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) { if (link(src.data, dest.data) == -1) {
// NOTE: Link can fail if we're trying to link across different volumes // NOTE: Link can fail if we're trying to link across different volumes
// so we fall back to a binary directory. // 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) { 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; 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_API DN_OSFile DN_OS_FileOpen(DN_Str8 path,
DN_OSFileOpen open_mode, DN_OSFileOpen open_mode,
DN_OSFileAccess access, DN_OSFileAccess access,
@ -678,9 +531,152 @@ DN_API void DN_OS_FileClose(DN_OSFile *file)
fclose(DN_CAST(FILE *) file->handle); fclose(DN_CAST(FILE *) file->handle);
*file = {}; *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) DN_API void DN_OS_Exit(int32_t exit_code)
{ {
exit(DN_CAST(int) 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)) { for (DN_ForIndexU(arg_index, cmd_line.size)) {
DN_Str8 arg = cmd_line.data[arg_index]; 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 // 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) { if (args->working_dir.size) {
prev_working_dir = get_current_dir_name(); 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) { if (chdir(working_dir.data) == -1) {
result.os_error_code = errno; result.os_error_code = errno;
DN_OS_ErrSinkAppendF( DN_OS_ErrSinkAppendF(
@ -1298,7 +1294,7 @@ DN_API void DN_Posix_ThreadSetName(DN_Str8 name)
(void)name; (void)name;
#else #else
DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr); 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_t thread = pthread_self();
pthread_setname_np(thread, (char *)copy.data); pthread_setname_np(thread, (char *)copy.data);
#endif #endif
@ -1322,7 +1318,7 @@ DN_API DN_POSIXProcSelfStatus DN_Posix_ProcSelfStatus()
if (!file.error) { if (!file.error) {
char buf[256]; char buf[256];
DN_Str8Builder builder = DN_Str8Builder_InitFromTLS(); DN_Str8Builder builder = DN_Str8Builder_FromTLS();
for (;;) { for (;;) {
DN_OSFileRead read = DN_OS_FileRead(&file, buf, sizeof(buf), nullptr); DN_OSFileRead read = DN_OS_FileRead(&file, buf, sizeof(buf), nullptr);
if (!read.success || read.bytes_read == 0) if (!read.success || read.bytes_read == 0)

View File

@ -1,6 +1,9 @@
#if !defined(DN_OS_TLS_H) #if !defined(DN_OS_TLS_H)
#define DN_OS_TLS_H #define DN_OS_TLS_H
#include "../dn_base_inc.h"
#include "../dn_os_inc.h"
// NOTE: DN_OSErrSink ///////////////////////////////////////////////////////////////////////////// // NOTE: DN_OSErrSink /////////////////////////////////////////////////////////////////////////////
enum DN_OSErrSinkMode enum DN_OSErrSinkMode
{ {
@ -87,7 +90,6 @@ struct DN_OSTLSInitArgs
DN_U64 err_sink_commit; 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_TLSInit (DN_OSTLS *tls, DN_OSTLSInitArgs args);
DN_API void DN_OS_TLSDeinit (DN_OSTLS *tls); DN_API void DN_OS_TLSDeinit (DN_OSTLS *tls);
DN_API DN_OSTLS * DN_OS_TLSGet (); 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 DN_Arena * DN_OS_TLSTopArena ();
DN_API void DN_OS_TLSBeginFrame (DN_Arena *frame_arena); DN_API void DN_OS_TLSBeginFrame (DN_Arena *frame_arena);
DN_API DN_Arena * DN_OS_TLSFrameArena (); 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_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_TLSTMem(...) DN_OS_TLSGetTMem(__VA_ARGS__, DN_OSTLSPushTMem_No)
#define DN_OS_TLSPushTMem(...) DN_OS_TLSGetTMem(__VA_ARGS__, DN_OSTLSPushTMem_Yes) #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);
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_ErrSinkBegin(mode) DN_OS_ErrSinkBegin_(mode, DN_CALL_SITE) #define DN_OS_ErrSinkBeginDefault() DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil)
#define DN_OS_ErrSinkBeginDefault() DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil) DN_API bool DN_OS_ErrSinkHasError (DN_OSErrSink *err);
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_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 DN_Str8 DN_OS_ErrSinkEndStr8 (DN_Arena *arena, DN_OSErrSink *err); DN_API void DN_OS_ErrSinkEndAndIgnore (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_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_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 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_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_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_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, ...);
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_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_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_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_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_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) \ #define DN_OS_ErrSinkAppendFV(error, error_code, fmt, args) \
do { \ do { \

View File

@ -298,7 +298,6 @@ DN_API DN_U64 DN_OS_PerfCounterNow()
return result; return result;
} }
#if !defined(DN_NO_OS_FILE_API)
static DN_U64 DN_W32_FileTimeToSeconds_(FILETIME const *time) static DN_U64 DN_W32_FileTimeToSeconds_(FILETIME const *time)
{ {
ULARGE_INTEGER time_large_int = {}; ULARGE_INTEGER time_large_int = {};
@ -308,73 +307,7 @@ static DN_U64 DN_W32_FileTimeToSeconds_(FILETIME const *time)
return result; return result;
} }
DN_API DN_OSPathInfo DN_OS_PathInfo(DN_Str8 path) DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *err)
{
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)
{ {
bool result = false; bool result = false;
DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); 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; 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_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr);
DN_Str16 src16 = DN_W32_Str8ToStr16(tmem.arena, src); DN_Str16 src16 = DN_W32_Str8ToStr16(tmem.arena, src);
DN_Str16 dest16 = DN_W32_Str8ToStr16(tmem.arena, dest); DN_Str16 dest16 = DN_W32_Str8ToStr16(tmem.arena, dest);
unsigned long flags = MOVEFILE_COPY_ALLOWED; unsigned long flags = MOVEFILE_COPY_ALLOWED;
if (overwrite) if (overwrite)
@ -412,128 +345,16 @@ DN_API bool DN_OS_MoveFile(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi
if (!result) { if (!result) {
DN_W32Error win_error = DN_W32_LastError(tmem.arena); DN_W32Error win_error = DN_W32_LastError(tmem.arena);
DN_OS_ErrSinkAppendF(err, DN_OS_ErrSinkAppendF(err,
win_error.code, win_error.code,
"Failed to move file '%.*s' to '%.*s': (%u) %.*s", "Failed to move file '%.*s' to '%.*s': (%u) %.*s",
DN_STR_FMT(src), DN_STR_FMT(src),
DN_STR_FMT(dest), DN_STR_FMT(dest),
win_error.code, win_error.code,
DN_STR_FMT(win_error.msg)); DN_STR_FMT(win_error.msg));
} }
return result; 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_API DN_OSFile DN_OS_FileOpen(DN_Str8 path, DN_OSFileOpen open_mode, DN_U32 access, DN_OSErrSink *err)
{ {
DN_OSFile result = {}; DN_OSFile result = {};
@ -680,7 +501,184 @@ DN_API void DN_OS_FileClose(DN_OSFile *file)
CloseHandle(file->handle); CloseHandle(file->handle);
*file = {}; *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 ///////////////////////////////////////////////////////////////////////////////// // NOTE: DN_OSExec /////////////////////////////////////////////////////////////////////////////////
DN_API void DN_OS_Exit(int32_t exit_code) DN_API void DN_OS_Exit(int32_t exit_code)