diff --git a/Single-Header/dn_single_header.cpp b/Single-Header/dn_single_header.cpp index 9ffdd21..1296670 100644 --- a/Single-Header/dn_single_header.cpp +++ b/Single-Header/dn_single_header.cpp @@ -1,11 +1,13 @@ -// Generated by the DN single header generator 2025-11-09 17:09:52 +// Generated by the DN single header generator 2025-11-16 21:35:27 #define DN_BASE_INC_CPP // DN: Single header generator inlined this file => #include "Base/dn_base.cpp" #define DN_BASE_CPP -// DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif DN_API bool DN_MemEq(void const *lhs, DN_USize lhs_size, void const *rhs, DN_USize rhs_size) { @@ -21,7 +23,7 @@ DN_API bool DN_MemEq(void const *lhs, DN_USize lhs_size, void const *rhs, DN_USi #include #endif -static DN_CPUFeatureDecl g_dn_cpu_feature_decl[DN_CPUFeature_Count]; +DN_CPUFeatureDecl g_dn_cpu_feature_decl[DN_CPUFeature_Count]; DN_API DN_U64 DN_AtomicSetValue64(DN_U64 volatile *target, DN_U64 value) { @@ -1699,6 +1701,13 @@ DN_API DN_Str8x32 DN_Str8x32FromFmt(DN_FMT_ATTRIB char const *fmt, ...) return result; } +DN_API DN_Str8x32 DN_Str8x32FromFmtV(DN_FMT_ATTRIB char const *fmt, va_list args) +{ + DN_Str8x32 result = {}; + DN_FmtVAppend(result.data, &result.size, sizeof(result.data), fmt, args); + return result; +} + DN_API DN_Str8x64 DN_Str8x64FromFmt(DN_FMT_ATTRIB char const *fmt, ...) { va_list args; @@ -1709,6 +1718,13 @@ DN_API DN_Str8x64 DN_Str8x64FromFmt(DN_FMT_ATTRIB char const *fmt, ...) return result; } +DN_API DN_Str8x64 DN_Str8x64FromFmtV(DN_FMT_ATTRIB char const *fmt, va_list args) +{ + DN_Str8x64 result = {}; + DN_FmtVAppend(result.data, &result.size, sizeof(result.data), fmt, args); + return result; +} + DN_API DN_Str8x128 DN_Str8x128FromFmt(DN_FMT_ATTRIB char const *fmt, ...) { va_list args; @@ -1719,6 +1735,13 @@ DN_API DN_Str8x128 DN_Str8x128FromFmt(DN_FMT_ATTRIB char const *fmt, ...) return result; } +DN_API DN_Str8x128 DN_Str8x128FromFmtV(DN_FMT_ATTRIB char const *fmt, va_list args) +{ + DN_Str8x128 result = {}; + DN_FmtVAppend(result.data, &result.size, sizeof(result.data), fmt, args); + return result; +} + DN_API DN_Str8x256 DN_Str8x256FromFmt(DN_FMT_ATTRIB char const *fmt, ...) { va_list args; @@ -1729,6 +1752,13 @@ DN_API DN_Str8x256 DN_Str8x256FromFmt(DN_FMT_ATTRIB char const *fmt, ...) return result; } +DN_API DN_Str8x256 DN_Str8x256FromFmtV(DN_FMT_ATTRIB char const *fmt, va_list args) +{ + DN_Str8x256 result = {}; + DN_FmtVAppend(result.data, &result.size, sizeof(result.data), fmt, args); + return result; +} + DN_API DN_Str8x32 DN_Str8x32FromU64(DN_U64 val, char separator) { DN_Str8x32 result = {}; @@ -4828,6 +4858,152 @@ DN_API void DN_LeakDump_(DN_LeakTracker *leak) // DN: Single header generator inlined this file => #include "OS/dn_os_tls.cpp" #define DN_OS_TLSCPP +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "dn_os_tls.h" +#if !defined(DN_OS_TLS_H) +#define DN_OS_TLS_H + +#if defined(_CLANGD) + // 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" +#endif + +// NOTE: DN_OSErrSink +enum DN_OSErrSinkMode +{ + DN_OSErrSinkMode_Nil, // Default behaviour to accumulate errors into the sink + DN_OSErrSinkMode_DebugBreakOnEndAndLog, // Debug break (int3) when error is encountered and the sink is ended by the 'end and log' functions. + DN_OSErrSinkMode_ExitOnError, // When an error is encountered, exit the program with the error code of the error that was caught. +}; + +struct DN_OSErrSinkMsg +{ + DN_I32 error_code; + DN_Str8 msg; + DN_CallSite call_site; + DN_OSErrSinkMsg *next; + DN_OSErrSinkMsg *prev; +}; + +struct DN_OSErrSinkNode +{ + DN_CallSite call_site; // Call site that the node was created + DN_OSErrSinkMode mode; // Controls how the sink behaves when an error is registered onto the sink. + DN_OSErrSinkMsg *msg_sentinel; // List of error messages accumulated for the current scope + DN_U64 arena_pos; // Position to reset the arena when the scope is ended +}; + +struct DN_OSErrSink +{ + DN_Arena * arena; // Dedicated allocator from the thread's local storage + DN_OSErrSinkNode stack[128]; // Each entry contains errors accumulated between a [begin, end] region of the active sink. + DN_USize stack_size; +}; + +enum DN_OSTLSArena +{ + DN_OSTLSArena_Main, // NOTE: Arena for permanent allocations + DN_OSTLSArena_ErrorSink, // NOTE: Arena for logging error information for this thread + + // NOTE: Per-thread scratch arenas (2 to prevent aliasing) + DN_OSTLSArena_TMem0, + DN_OSTLSArena_TMem1, + + DN_OSTLSArena_Count, +}; + +struct DN_OSTLS +{ + DN_B32 init; // Flag to track if TLS has been initialised + DN_U64 thread_id; + DN_CallSite call_site; // Stores call-site information when requested by thread + DN_OSErrSink err_sink; // Error handling state + DN_Arena arenas[DN_OSTLSArena_Count]; // Default arenas that the thread has access to implicitly + DN_Arena * arena_stack[8]; // Active stack of arenas push/popped arenas on into the TLS + DN_USize arena_stack_index; + + DN_Arena * frame_arena; + char name[64]; + DN_U8 name_size; +}; + +// Push the temporary memory arena when retrieved, popped when the arena goes +// out of scope. Pushed arenas are used automatically as the allocator in TLS +// suffixed function. +enum DN_OSTLSPushTMem +{ + DN_OSTLSPushTMem_No, + DN_OSTLSPushTMem_Yes, +}; + +struct DN_OSTLSTMem +{ + DN_OSTLSTMem(DN_OSTLS *context, uint8_t context_index, DN_OSTLSPushTMem push_scratch); + ~DN_OSTLSTMem(); + DN_Arena *arena; + DN_B32 destructed; + DN_OSTLSPushTMem push_arena; + DN_ArenaTempMem temp_mem; +}; + +struct DN_OSTLSInitArgs +{ + DN_U64 reserve; + DN_U64 commit; + DN_U64 err_sink_reserve; + DN_U64 err_sink_commit; +}; + +DN_API void DN_OS_TLSInit (DN_OSTLS *tls, DN_OSTLSInitArgs args); +DN_API void DN_OS_TLSDeinit (DN_OSTLS *tls); +DN_API DN_OSTLS * DN_OS_TLSGet (); +DN_API void DN_OS_TLSSetCurrentThreadTLS (DN_OSTLS *tls); +DN_API DN_Arena * DN_OS_TLSArena (); +DN_API DN_OSTLSTMem DN_OS_TLSGetTMem (void const *conflict_arena, DN_OSTLSPushTMem push_tmp_mem); +DN_API void DN_OS_TLSPushArena (DN_Arena *arena); +DN_API void DN_OS_TLSPopArena (); +DN_API DN_Arena * DN_OS_TLSTopArena (); +DN_API void DN_OS_TLSBeginFrame (DN_Arena *frame_arena); +DN_API DN_Arena * DN_OS_TLSFrameArena (); +#define DN_OS_TLSSaveCallSite do { DN_OS_TLSGet()->call_site = DN_CALL_SITE; } while (0) +#define DN_OS_TLSTMem(...) DN_OS_TLSGetTMem(__VA_ARGS__, DN_OSTLSPushTMem_No) +#define DN_OS_TLSPushTMem(...) DN_OS_TLSGetTMem(__VA_ARGS__, DN_OSTLSPushTMem_Yes) + +DN_API DN_OSErrSink * DN_OS_ErrSinkBegin_ (DN_OSErrSinkMode mode, DN_CallSite call_site); +#define DN_OS_ErrSinkBegin(mode) DN_OS_ErrSinkBegin_(mode, DN_CALL_SITE) +#define DN_OS_ErrSinkBeginDefault() DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil) +DN_API bool DN_OS_ErrSinkHasError (DN_OSErrSink *err); +DN_API DN_OSErrSinkMsg * DN_OS_ErrSinkEnd (DN_Arena *arena, DN_OSErrSink *err); +DN_API DN_Str8 DN_OS_ErrSinkEndStr8 (DN_Arena *arena, DN_OSErrSink *err); +DN_API void DN_OS_ErrSinkEndAndIgnore (DN_OSErrSink *err); +DN_API bool DN_OS_ErrSinkEndAndLogError_ (DN_OSErrSink *err, DN_CallSite call_site, DN_Str8 msg); +DN_API bool DN_OS_ErrSinkEndAndLogErrorFV_ (DN_OSErrSink *err, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API bool DN_OS_ErrSinkEndAndLogErrorF_ (DN_OSErrSink *err, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, ...); +DN_API void DN_OS_ErrSinkEndAndExitIfErrorF_ (DN_OSErrSink *err, DN_CallSite call_site, DN_U32 exit_val, DN_FMT_ATTRIB char const *fmt, ...); +DN_API void DN_OS_ErrSinkEndAndExitIfErrorFV_ (DN_OSErrSink *err, DN_CallSite call_site, DN_U32 exit_val, DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API void DN_OS_ErrSinkAppendFV_ (DN_OSErrSink *err, DN_U32 error_code, DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API void DN_OS_ErrSinkAppendF_ (DN_OSErrSink *err, DN_U32 error_code, DN_FMT_ATTRIB char const *fmt, ...); +#define DN_OS_ErrSinkEndAndLogError(err, err_msg) DN_OS_ErrSinkEndAndLogError_(err, DN_CALL_SITE, err_msg) +#define DN_OS_ErrSinkEndAndLogErrorFV(err, fmt, args) DN_OS_ErrSinkEndAndLogErrorFV_(err, DN_CALL_SITE, fmt, args) +#define DN_OS_ErrSinkEndAndLogErrorF(err, fmt, ...) DN_OS_ErrSinkEndAndLogErrorF_(err, DN_CALL_SITE, fmt, ##__VA_ARGS__) +#define DN_OS_ErrSinkEndAndExitIfErrorFV(err, exit_val, fmt, args) DN_OS_ErrSinkEndAndExitIfErrorFV_(err, DN_CALL_SITE, exit_val, fmt, args) +#define DN_OS_ErrSinkEndAndExitIfErrorF(err, exit_val, fmt, ...) DN_OS_ErrSinkEndAndExitIfErrorF_(err, DN_CALL_SITE, exit_val, fmt, ##__VA_ARGS__) + +#define DN_OS_ErrSinkAppendFV(error, error_code, fmt, args) \ + do { \ + DN_OS_TLSSaveCallSite; \ + DN_OS_ErrSinkAppendFV_(error, error_code, fmt, args); \ + } while (0) + +#define DN_OS_ErrSinkAppendF(error, error_code, fmt, ...) \ + do { \ + DN_OS_TLSSaveCallSite; \ + DN_OS_ErrSinkAppendF_(error, error_code, fmt, ##__VA_ARGS__); \ + } while (0) + +#endif // defined(DN_OS_TLS_H) +#endif + // NOTE: DN_OSTLS //////////////////////////////////////////////////////////////////////////////////// DN_OSTLSTMem::DN_OSTLSTMem(DN_OSTLS *tls, DN_U8 arena_index, DN_OSTLSPushTMem push_tmem) { @@ -4894,10 +5070,10 @@ DN_API void DN_OS_TLSSetCurrentThreadTLS(DN_OSTLS *tls) DN_API DN_OSTLS *DN_OS_TLSGet() { - DN_Assert(g_dn_curr_thread_tls && - "DN must be initialised (via DN_Core_Init) before calling any functions depending on " - "TLS if this is the main thread, OR, the created thread has not called " - "SetCurrentThreadTLS yet so the TLS data structure hasn't been assigned yet"); + DN_RawAssert(g_dn_curr_thread_tls && + "DN must be initialised (via DN_Core_Init) before calling any functions depending on " + "TLS if this is the main thread, OR, the created thread has not called " + "SetCurrentThreadTLS yet so the TLS data structure hasn't been assigned yet"); return g_dn_curr_thread_tls; } @@ -5226,8 +5402,10 @@ DN_API void DN_OS_ErrSinkAppendF_(DN_OSErrSink *err, DN_U32 error_code, DN_FMT_A // DN: Single header generator inlined this file => #include "OS/dn_os.cpp" #define DN_OS_CPP -// 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" +#if defined(_CLANGD) + // 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" +#endif #if defined(DN_PLATFORM_POSIX) #include // get_nprocs @@ -5959,8 +6137,11 @@ DN_API DN_OSHttpResponse DN_OS_HttpRequest(DN_Arena *arena, DN_Str8 host, DN_Str // DN: Single header generator inlined this file => #include "OS/dn_os_allocator.cpp" #define DN_OS_ALLOCATOR_CPP -// 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" +#if defined(_CLANGD) + // 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" + // DN: Single header generator commented out this header => #include "../dn_inc.h" +#endif static void *DN_ArenaBasicAllocFromOSHeap(DN_USize size) { @@ -5993,6 +6174,59 @@ DN_API DN_Arena DN_ArenaFromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags fl // DN: Single header generator inlined this file => #include "OS/dn_os_containers.cpp" #define DN_OS_CONTAINERS_CPP +// DN: Single header generator commented out this header => #include "dn_os_containers.h" +#if !defined(DN_OS_CONTAINERS_H) +#define DN_OS_CONTAINERS_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +// NOTE: DN_VArray +// TODO(doyle): Add an API for shrinking the array by decomitting pages back to the OS. +template struct DN_VArray +{ + T *data; // Pointer to the start of the array items in the block of memory + DN_USize size; // Number of items currently in the array + DN_USize max; // Maximum number of items this array can store + DN_USize commit; // Bytes committed + + T *begin() { return data; } + T *end () { return data + size; } + T const *begin() const { return data; } + T const *end () const { return data + size; } +}; + +template DN_VArray DN_VArray_InitByteSize (DN_USize byte_size); +template DN_VArray DN_VArray_Init (DN_USize max); +template DN_VArray DN_VArray_InitSlice (DN_Slice slice, DN_USize max); +template DN_VArray DN_VArray_InitCArray (T const (&items)[N], DN_USize max); +template void DN_VArray_Deinit (DN_VArray *array); +template bool DN_VArray_IsValid (DN_VArray const *array); +template DN_Slice DN_VArray_Slice (DN_VArray const *array); +template bool DN_VArray_Reserve (DN_VArray *array, DN_USize count); +template T * DN_VArray_AddArray (DN_VArray *array, T const *items, DN_USize count); +template T * DN_VArray_AddCArray (DN_VArray *array, T const (&items)[N]); +template T * DN_VArray_Add (DN_VArray *array, T const &item); +#define DN_VArray_AddArrayAssert(...) DN_HardAssert(DN_VArray_AddArray(__VA_ARGS__)) +#define DN_VArray_AddCArrayAssert(...) DN_HardAssert(DN_VArray_AddCArray(__VA_ARGS__)) +#define DN_VArray_AddAssert(...) DN_HardAssert(DN_VArray_Add(__VA_ARGS__)) +template T * DN_VArray_MakeArray (DN_VArray *array, DN_USize count, DN_ZMem z_mem); +template T * DN_VArray_Make (DN_VArray *array, DN_ZMem z_mem); +#define DN_VArray_MakeArrayAssert(...) DN_HardAssert(DN_VArray_MakeArray(__VA_ARGS__)) +#define DN_VArray_MakeAssert(...) DN_HardAssert(DN_VArray_Make(__VA_ARGS__)) +template T * DN_VArray_InsertArray (DN_VArray *array, DN_USize index, T const *items, DN_USize count); +template T * DN_VArray_InsertCArray (DN_VArray *array, DN_USize index, T const (&items)[N]); +template T * DN_VArray_Insert (DN_VArray *array, DN_USize index, T const &item); +#define DN_VArray_InsertArrayAssert(...) DN_HardAssert(DN_VArray_InsertArray(__VA_ARGS__)) +#define DN_VArray_InsertCArrayAssert(...) DN_HardAssert(DN_VArray_InsertCArray(__VA_ARGS__)) +#define DN_VArray_InsertAssert(...) DN_HardAssert(DN_VArray_Insert(__VA_ARGS__)) +template T DN_VArray_PopFront (DN_VArray *array, DN_USize count); +template T DN_VArray_PopBack (DN_VArray *array, DN_USize count); +template DN_ArrayEraseResult DN_VArray_EraseRange (DN_VArray *array, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase); +template void DN_VArray_Clear (DN_VArray *array, DN_ZMem z_mem); +#endif // !defined(DN_OS_CONTAINERS_H) + /* //////////////////////////////////////////////////////////////////////////////////////////////////// // @@ -6367,8 +6601,10 @@ DN_API void DN_OS_PrintLnFVStyle(DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_ // DN: Single header generator inlined this file => #include "OS/dn_os_string.cpp" #define DN_OS_STRING_CPP -// 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" +#if defined(_CLANGD) + // 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" +#endif // NOTE: DN_Str8 DN_API DN_Str8 DN_Str8FromFmtArenaFrame(DN_FMT_ATTRIB char const *fmt, ...) @@ -6673,10 +6909,15 @@ DN_API DN_Str8 DN_Str8BuilderBuildFromOSHeap(DN_Str8Builder const *builder) // DN: Single header generator inlined this file => #include "OS/dn_os_posix.cpp" #define DN_OS_POSIX_CPP +#if defined(_CLANGD) + // 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" +#endif + #include // readdir, opendir, closedir #include -// NOTE: DN_OSMem ////////////////////////////////////////////////////////////////////////////////// +// NOTE: DN_OSMem static DN_U32 DN_OS_MemConvertPageToOSFlags_(DN_U32 protect) { DN_Assert((protect & ~DN_MemPage_All) == 0); @@ -8302,6 +8543,7 @@ DN_API int DN_OS_MemProtect(void *ptr, DN_USize size, DN_U32 page_flags) DN_API void *DN_OS_MemAlloc(DN_USize size, DN_ZMem z_mem) { + DN_RawAssert(g_dn_->init_flags & DN_InitFlags_OS && "DN must be initialised with the OS flag"); DN_U32 flags = z_mem == DN_ZMem_Yes ? HEAP_ZERO_MEMORY : 0; DN_Assert(size <= DN_Cast(DWORD)(-1)); void *result = HeapAlloc(GetProcessHeap(), flags, DN_Cast(DWORD) size); @@ -10252,19 +10494,7709 @@ DN_API void DN_StackTraceReloadSymbols() } #define DN_INC_CPP -// DN: Single header generator inlined this file => #include "dn_inc.h" +#if defined(_CLANGD) + // DN: Single header generator inlined this file => #include "dn_inc.h" #if !defined(DN_INC_H) #define DN_INC_H -struct DN_Core +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "dn_base_inc.h" +#if !defined(DN_BASE_INC_H) +#define DN_BASE_INC_H + +// NOTE: DN configuration +// All the following configuration options are optional. If omitted, DN has default behaviours to +// handle the various options. +// +// Platform Target +// Define one of the following directives to configure this library to compile for that platform. +// By default, the library will auto-detect the current host platform and select that as the +// target platform. +// +// DN_PLATFORM_EMSCRIPTEN +// DN_PLATFORM_POSIX +// DN_PLATFORM_WIN32 +// +// For example +// +// #define DN_PLATFORM_WIN32 +// +// Will ensure that is included and the OS layer is implemented using Win32 +// primitives. +// +// Static functions +// All public functions in the DN library are prefixed with the macro '#define DN_API'. By +// default 'DN_API' is not defined to anything. Define +// +// DN_STATIC_API +// +// To replace all the prefixed with 'static' ensuring that the functions in the library do not +// export an entry into the linking table and thereby optimise compilation times as the linker +// will not try to resolve symbols from other translation units from the the unit including the +// DN library. +// +// Using the in-built replacement header for (requires dn_os_inc.h) +// If you are building DN for the Windows platform, is a large legacy header that +// applications have to link to use Windows syscalls. By default DN library uses a replacement +// header for all the Windows functions that it uses in the OS layer removing the need to include +// to improve compilation times. This can be disabled by defining: +// +// DN_NO_WINDOWS_H_REPLACEMENT_HEADER +// +// To instead use . DN automatically detects if is included in an earlier +// translation unit and will automatically disable the in-built replacement header in which case +// this does not need to be defined. +// +// Freestanding +// The base layer can be used without an OS implementation by defining DN_FREESTANDING like: +// +// #define DN_FREESTANDING +// +// This means functionality that relies on the OS like printing, memory allocation, stack traces +// and so forth are disabled. + +// DN: Single header generator commented out this header => #include "Base/dn_base_compiler.h" +#if !defined(DN_BASE_COMPILER_H) +#define DN_BASE_COMPILER_H + +// NOTE: Compiler identification +// Warning! Order is important here, clang-cl on Windows defines _MSC_VER +#if defined(_MSC_VER) + #if defined(__clang__) + #define DN_COMPILER_CLANG_CL + #define DN_COMPILER_CLANG + #else + #define DN_COMPILER_MSVC + #endif +#elif defined(__clang__) + #define DN_COMPILER_CLANG +#elif defined(__GNUC__) + #define DN_COMPILER_GCC +#endif + +// NOTE: __has_feature +// MSVC for example does not support the feature detection macro for instance so we compile it out +#if defined(__has_feature) + #define DN_HAS_FEATURE(expr) __has_feature(expr) +#else + #define DN_HAS_FEATURE(expr) 0 +#endif + +// NOTE: __has_builtin +// MSVC for example does not support the feature detection macro for instance so we compile it out +#if defined(__has_builtin) + #define DN_HAS_BUILTIN(expr) __has_builtin(expr) +#else + #define DN_HAS_BUILTIN(expr) 0 +#endif + +// NOTE: Warning suppression macros +#if defined(DN_COMPILER_MSVC) + #define DN_MSVC_WARNING_PUSH __pragma(warning(push)) + #define DN_MSVC_WARNING_DISABLE(...) __pragma(warning(disable :##__VA_ARGS__)) + #define DN_MSVC_WARNING_POP __pragma(warning(pop)) +#else + #define DN_MSVC_WARNING_PUSH + #define DN_MSVC_WARNING_DISABLE(...) + #define DN_MSVC_WARNING_POP +#endif + +#if defined(DN_COMPILER_CLANG) || defined(DN_COMPILER_GCC) || defined(DN_COMPILER_CLANG_CL) + #define DN_GCC_WARNING_PUSH _Pragma("GCC diagnostic push") + #define DN_GCC_WARNING_DISABLE_HELPER_0(x) #x + #define DN_GCC_WARNING_DISABLE_HELPER_1(y) DN_GCC_WARNING_DISABLE_HELPER_0(GCC diagnostic ignored #y) + #define DN_GCC_WARNING_DISABLE(warning) _Pragma(DN_GCC_WARNING_DISABLE_HELPER_1(warning)) + #define DN_GCC_WARNING_POP _Pragma("GCC diagnostic pop") +#else + #define DN_GCC_WARNING_PUSH + #define DN_GCC_WARNING_DISABLE(...) + #define DN_GCC_WARNING_POP +#endif + +// NOTE: Host OS identification +#if defined(_WIN32) + #define DN_OS_WIN32 +#elif defined(__gnu_linux__) || defined(__linux__) + #define DN_OS_UNIX +#endif + +// NOTE: Platform identification +#if !defined(DN_PLATFORM_EMSCRIPTEN) && \ + !defined(DN_PLATFORM_POSIX) && \ + !defined(DN_PLATFORM_WIN32) + #if defined(__aarch64__) || defined(_M_ARM64) + #define DN_PLATFORM_ARM64 + #elif defined(__EMSCRIPTEN__) + #define DN_PLATFORM_EMSCRIPTEN + #elif defined(DN_OS_WIN32) + #define DN_PLATFORM_WIN32 + #else + #define DN_PLATFORM_POSIX + #endif +#endif + +// NOTE: Windows crap +#if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) + #if defined(_CRT_SECURE_NO_WARNINGS) + #define DN_CRT_SECURE_NO_WARNINGS_PREVIOUSLY_DEFINED + #else + #define _CRT_SECURE_NO_WARNINGS + #endif +#endif + +// NOTE: Force Inline +#if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) + #define DN_FORCE_INLINE __forceinline +#else + #define DN_FORCE_INLINE inline __attribute__((always_inline)) +#endif + +// NOTE: Function/Variable Annotations +#if defined(DN_STATIC_API) + #define DN_API static +#else + #define DN_API +#endif + +// NOTE: C/CPP Literals +// Declare struct literals that work in both C and C++ because the syntax is different between +// languages. +#if 0 + struct Foo { int a; } + struct Foo foo = DN_LITERAL(Foo){32}; // Works on both C and C++ +#endif + +#if defined(__cplusplus) + #define DN_Literal(T) T +#else + #define DN_Literal(T) (T) +#endif + +// NOTE: Thread Locals +#if defined(__cplusplus) + #define DN_THREAD_LOCAL thread_local +#else + #define DN_THREAD_LOCAL _Thread_local +#endif + +// NOTE: C variadic argument annotations +// TODO: Other compilers +#if defined(DN_COMPILER_MSVC) + #define DN_FMT_ATTRIB _Printf_format_string_ +#else + #define DN_FMT_ATTRIB +#endif + +// NOTE: Type Cast +#define DN_Cast(val) (val) + +// NOTE: Zero initialisation macro +#if defined(__cplusplus) + #define DN_ZeroInit {} +#else + #define DN_ZeroInit {0} +#endif + +// NOTE: Address sanitizer +#if !defined(DN_ASAN_POISON) + #define DN_ASAN_POISON 0 +#endif + +#if !defined(DN_ASAN_VET_POISON) + #define DN_ASAN_VET_POISON 0 +#endif + +#define DN_ASAN_POISON_ALIGNMENT 8 + +#if !defined(DN_ASAN_POISON_GUARD_SIZE) + #define DN_ASAN_POISON_GUARD_SIZE 128 +#endif + +#if DN_HAS_FEATURE(address_sanitizer) || defined(__SANITIZE_ADDRESS__) + #include +#endif +#endif // !defined(DN_BASE_COMPILER_H) +// DN: Single header generator commented out this header => #include "Base/dn_base.h" +#if !defined(DN_BASE_H) +#define DN_BASE_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +// NOTE: Macros +#define DN_Stringify(x) #x +#define DN_TokenCombine2(x, y) x ## y +#define DN_TokenCombine(x, y) DN_TokenCombine2(x, y) + +#include // va_list +#include +#include +#include +#include // PRIu64... + +#if !defined(DN_OS_WIN32) +#include // exit() +#endif + +#define DN_ForIndexU(index, size) DN_USize index = 0; index < size; index++ +#define DN_ForIndexI(index, size) DN_ISize index = 0; index < size; index++ +#define DN_ForItSize(it, T, array, size) struct { DN_USize index; T *data; } it = {0, &(array)[0]}; it.index < (size); it.index++, it.data = (array) + it.index +#define DN_ForItSizeReverse(it, T, array, size) struct { DN_USize index; T *data; } it = {(size) - 1, &(array)[size - 1]}; it.index < (size); it.index--, it.data = (array) + it.index +#define DN_ForIt(it, T, array) struct { DN_USize index; T *data; } it = {0, &(array)->data[0]}; it.index < (array)->size; it.index++, it.data = ((array)->data) + it.index +#define DN_ForLinkedListIt(it, T, list) struct { DN_USize index; T *data; } it = {0, list}; it.data; it.index++, it.data = ((it).data->next) +#define DN_ForItCArray(it, T, array) struct { DN_USize index; T *data; } it = {0, &(array)[0]}; it.index < DN_ArrayCountU(array); it.index++, it.data = (array) + it.index + +#define DN_AlignUpPowerOfTwo(value, pot) (((uintptr_t)(value) + ((uintptr_t)(pot) - 1)) & ~((uintptr_t)(pot) - 1)) +#define DN_AlignDownPowerOfTwo(value, pot) ((uintptr_t)(value) & ~((uintptr_t)(pot) - 1)) +#define DN_IsPowerOfTwo(value) ((((uintptr_t)(value)) & (((uintptr_t)(value)) - 1)) == 0) +#define DN_IsPowerOfTwoAligned(value, pot) ((((uintptr_t)value) & (((uintptr_t)pot) - 1)) == 0) + +// NOTE: String.h Dependencies +#if !defined(DN_Memcpy) || !defined(DN_Memset) || !defined(DN_Memcmp) || !defined(DN_Memmove) + #include + #if !defined(DN_Memcpy) + #define DN_Memcpy(dest, src, count) memcpy((dest), (src), (count)) + #endif + #if !defined(DN_Memset) + #define DN_Memset(dest, value, count) memset((dest), (value), (count)) + #endif + #if !defined(DN_Memcmp) + #define DN_Memcmp(lhs, rhs, count) memcmp((lhs), (rhs), (count)) + #endif + #if !defined(DN_Memmove) + #define DN_Memmove(dest, src, count) memmove((dest), (src), (count)) + #endif +#endif + +// NOTE: Math.h Dependencies +#if !defined(DN_SqrtF32) || !defined(DN_SinF32) || !defined(DN_CosF32) || !defined(DN_TanF32) + #include + #if !defined(DN_SqrtF32) + #define DN_SqrtF32(val) sqrtf(val) + #endif + #if !defined(DN_SinF32) + #define DN_SinF32(val) sinf(val) + #endif + #if !defined(DN_CosF32) + #define DN_CosF32(val) cosf(val) + #endif + #if !defined(DN_TanF32) + #define DN_TanF32(val) tanf(val) + #endif +#endif + +// NOTE: Math +#define DN_PiF32 3.14159265359f + +#define DN_DegreesToRadians(degrees) ((degrees) * (DN_PI / 180.0f)) +#define DN_RadiansToDegrees(radians) ((radians) * (180.f * DN_PI)) + +#define DN_Abs(val) (((val) < 0) ? (-(val)) : (val)) +#define DN_Max(a, b) (((a) > (b)) ? (a) : (b)) +#define DN_Min(a, b) (((a) < (b)) ? (a) : (b)) +#define DN_Clamp(val, lo, hi) DN_Max(DN_Min(val, hi), lo) +#define DN_Squared(val) ((val) * (val)) + +#define DN_Swap(a, b) \ + do { \ + auto temp = a; \ + a = b; \ + b = temp; \ + } while (0) + +// NOTE: Size +#define DN_SizeOfI(val) DN_Cast(ptrdiff_t)sizeof(val) +#define DN_ArrayCountU(array) (sizeof(array)/(sizeof((array)[0]))) +#define DN_ArrayCountI(array) (DN_ISize)DN_ArrayCountU(array) +#define DN_CharCountU(string) (sizeof(string) - 1) + +// NOTE: SI Byte +#define DN_Bytes(val) ((DN_U64)val) +#define DN_Kilobytes(val) ((DN_U64)1024 * DN_Bytes(val)) +#define DN_Megabytes(val) ((DN_U64)1024 * DN_Kilobytes(val)) +#define DN_Gigabytes(val) ((DN_U64)1024 * DN_Megabytes(val)) + +// NOTE: Time +#define DN_MsFromSec(val) ((val) * 1000ULL) +#define DN_SecFromMins(val) ((val) * 60ULL) +#define DN_SecFromHours(val) (DN_SecFromMins(val) * 60ULL) +#define DN_SecFromDays(val) (DN_SecFromHours(val) * 24ULL) +#define DN_SecFromWeeks(val) (DN_SecFromDays(val) * 7ULL) +#define DN_SecFromYears(val) (DN_SecFromWeeks(val) * 52ULL) + +// NOTE: Debug Break +#if !defined(DN_DebugBreak) + #if defined(NDEBUG) + #define DN_DebugBreak + #else + #if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) + #define DN_DebugBreak __debugbreak() + #elif DN_HAS_BUILTIN(__builtin_debugtrap) + #define DN_DebugBreak __builtin_debugtrap() + #elif DN_HAS_BUILTIN(__builtin_trap) || defined(DN_COMPILER_GCC) + #define DN_DebugBreak __builtin_trap() + #else + #include + #if defined(SIGTRAP) + #define DN_DebugBreak raise(SIGTRAP) + #else + #define DN_DebugBreak raise(SIGABRT) + #endif + #endif + #endif +#endif + +// NOTE: Byte swaps +#define DN_ByteSwap64(u64) (((((u64) >> 56) & 0xFF) << 0) | \ + ((((u64) >> 48) & 0xFF) << 8) | \ + ((((u64) >> 40) & 0xFF) << 16) | \ + ((((u64) >> 32) & 0xFF) << 24) | \ + ((((u64) >> 24) & 0xFF) << 32) | \ + ((((u64) >> 16) & 0xFF) << 40) | \ + ((((u64) >> 8) & 0xFF) << 48) | \ + ((((u64) >> 0) & 0xFF) << 56)) + +// NOTE: Types +typedef intptr_t DN_ISize; +typedef uintptr_t DN_USize; + +typedef int8_t DN_I8; +typedef int16_t DN_I16; +typedef int32_t DN_I32; +typedef int64_t DN_I64; + +typedef uint8_t DN_U8; +typedef uint16_t DN_U16; +typedef uint32_t DN_U32; +typedef uint64_t DN_U64; + +typedef uintptr_t DN_UPtr; +typedef float DN_F32; +typedef double DN_F64; +typedef unsigned int DN_UInt; +typedef DN_I32 DN_B32; + +#define DN_F32_MAX 3.402823466e+38F +#define DN_F32_MIN 1.175494351e-38F +#define DN_F64_MAX 1.7976931348623158e+308 +#define DN_F64_MIN 2.2250738585072014e-308 +#define DN_USIZE_MAX UINTPTR_MAX +#define DN_ISIZE_MAX INTPTR_MAX +#define DN_ISIZE_MIN INTPTR_MIN + +enum DN_ZMem { - DN_USize mem_allocs_frame; - DN_LeakTracker leak; - #if defined(DN_OS_H) - DN_OSCore os; + DN_ZMem_No, // Memory can be handed out without zero-ing it out + DN_ZMem_Yes, // Memory should be zero-ed out before giving to the callee +}; + +struct DN_Str8 +{ + char *data; // The bytes of the string + DN_USize size; // The number of bytes in the string +}; + +struct DN_Str8x32 { char data[32]; DN_USize size; }; +struct DN_Str8x64 { char data[64]; DN_USize size; }; +struct DN_Str8x128 { char data[128]; DN_USize size; }; +struct DN_Str8x256 { char data[256]; DN_USize size; }; + +struct DN_Hex32 { char data[32]; }; +struct DN_Hex64 { char data[64]; }; +struct DN_Hex128 { char data[128]; }; + +struct DN_HexU64Str8 +{ + char data[(sizeof(DN_U64) * 2) + 1 /*null-terminator*/]; + DN_U8 size; +}; + +enum DN_HexFromU64Type +{ + DN_HexFromU64Type_Nil, + DN_HexFromU64Type_Uppercase, +}; + +struct DN_Str16 // A pointer and length style string that holds slices to UTF16 bytes. +{ + wchar_t *data; // The UTF16 bytes of the string + DN_USize size; // The number of characters in the string +}; + +struct DN_U8x16 { DN_U8 data[16]; }; +struct DN_U8x32 { DN_U8 data[32]; }; +struct DN_U8x64 { DN_U8 data[64]; }; + +template +struct DN_Slice // A pointer and length container of data +{ + T *data; + DN_USize size; + + T *begin() { return data; } + T *end() { return data + size; } + T const *begin() const { return data; } + T const *end() const { return data + size; } +}; + +struct DN_CallSite +{ + DN_Str8 file; + DN_Str8 function; + DN_U32 line; +}; + +#define DN_CALL_SITE DN_CallSite { DN_Str8Lit(__FILE__), DN_Str8Lit(__func__), __LINE__ } + +// NOTE: Defer Macro +#if defined(__cplusplus) +template +struct DN_Defer +{ + Procedure proc; + DN_Defer(Procedure p) : proc(p) {} + ~DN_Defer() { proc(); } +}; + +struct DN_DeferHelper +{ + template + DN_Defer operator+(Lambda lambda) { return DN_Defer(lambda); }; +}; + +#define DN_UniqueName(prefix) DN_TokenCombine(prefix, __LINE__) +#define DN_DEFER const auto DN_UniqueName(defer_lambda_) = DN_DeferHelper() + [&]() +#endif // defined(__cplusplus) + +#define DN_DeferLoop(begin, end) \ + bool DN_UniqueName(once) = (begin, true); \ + DN_UniqueName(once); \ + end, DN_UniqueName(once) = false + + +// NOTE: Intrinsics +// NOTE: DN_AtomicAdd/Exchange return the previous value store in the target +#if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) + #include + #define DN_AtomicCompareExchange64(dest, desired_val, prev_val) _InterlockedCompareExchange64((__int64 volatile *)dest, desired_val, prev_val) + #define DN_AtomicCompareExchange32(dest, desired_val, prev_val) _InterlockedCompareExchange((long volatile *)dest, desired_val, prev_val) + + #define DN_AtomicLoadU64(target) *(target) + #define DN_AtomicLoadU32(target) *(target) + #define DN_AtomicAddU32(target, value) _InterlockedExchangeAdd((long volatile *)target, value) + #define DN_AtomicAddU64(target, value) _InterlockedExchangeAdd64((__int64 volatile *)target, value) + #define DN_AtomicSubU32(target, value) DN_AtomicAddU32(DN_Cast(long volatile *) target, (long)-value) + #define DN_AtomicSubU64(target, value) DN_AtomicAddU64(target, (DN_U64) - value) + + #define DN_CountLeadingZerosU64(value) __lzcnt64(value) + #define DN_CountLeadingZerosU32(value) __lzcnt(value) + #define DN_CPUGetTSC() __rdtsc() + #define DN_CompilerReadBarrierAndCPUReadFence _ReadBarrier(); _mm_lfence() + #define DN_CompilerWriteBarrierAndCPUWriteFence _WriteBarrier(); _mm_sfence() +#elif defined(DN_COMPILER_GCC) || defined(DN_COMPILER_CLANG) + #if defined(__ANDROID__) + #elif defined(DN_PLATFORM_EMSCRIPTEN) + #if !defined(__wasm_simd128__) + #error DN_Base requires -msse2 to be passed to Emscripten + #endif + #include + #else + #include + #endif + + #define DN_AtomicLoadU64(target) __atomic_load_n(x, __ATOMIC_SEQ_CST) + #define DN_AtomicLoadU32(target) __atomic_load_n(x, __ATOMIC_SEQ_CST) + #define DN_AtomicAddU32(target, value) __atomic_fetch_add(target, value, __ATOMIC_ACQ_REL) + #define DN_AtomicAddU64(target, value) __atomic_fetch_add(target, value, __ATOMIC_ACQ_REL) + #define DN_AtomicSubU32(target, value) __atomic_fetch_sub(target, value, __ATOMIC_ACQ_REL) + #define DN_AtomicSubU64(target, value) __atomic_fetch_sub(target, value, __ATOMIC_ACQ_REL) + + #define DN_CountLeadingZerosU64(value) __builtin_clzll(value) + #define DN_CountLeadingZerosU32(value) __builtin_clzl(value) + + #if defined(DN_COMPILER_GCC) + #define DN_CPUGetTSC() __rdtsc() + #else + #define DN_CPUGetTSC() __builtin_readcyclecounter() + #endif + + #if defined(DN_PLATFORM_EMSCRIPTEN) + #define DN_CompilerReadBarrierAndCPUReadFence + #define DN_CompilerWriteBarrierAndCPUWriteFence + #else + #define DN_CompilerReadBarrierAndCPUReadFence asm volatile("lfence" ::: "memory") + #define DN_CompilerWriteBarrierAndCPUWriteFence asm volatile("sfence" ::: "memory") + #endif +#else + #error "Compiler not supported" +#endif + +#if defined(__aarch64__) || defined(_M_X64) || defined(__x86_64__) || defined(__x86_64) + #define DN_CountLeadingZerosUSize(value) DN_CountLeadingZerosU64(value) +#else + #define DN_CountLeadingZerosUSize(value) DN_CountLeadingZerosU32(value) +#endif + +struct DN_CPURegisters +{ + int eax; + int ebx; + int ecx; + int edx; +}; + +union DN_CPUIDResult +{ + DN_CPURegisters reg; + int values[4]; +}; + +struct DN_CPUIDArgs { int eax; int ecx; }; + +#define DN_CPU_FEAT_XMACRO \ + DN_CPU_FEAT_XENTRY(3DNow) \ + DN_CPU_FEAT_XENTRY(3DNowExt) \ + DN_CPU_FEAT_XENTRY(ABM) \ + DN_CPU_FEAT_XENTRY(AES) \ + DN_CPU_FEAT_XENTRY(AVX) \ + DN_CPU_FEAT_XENTRY(AVX2) \ + DN_CPU_FEAT_XENTRY(AVX512F) \ + DN_CPU_FEAT_XENTRY(AVX512DQ) \ + DN_CPU_FEAT_XENTRY(AVX512IFMA) \ + DN_CPU_FEAT_XENTRY(AVX512PF) \ + DN_CPU_FEAT_XENTRY(AVX512ER) \ + DN_CPU_FEAT_XENTRY(AVX512CD) \ + DN_CPU_FEAT_XENTRY(AVX512BW) \ + DN_CPU_FEAT_XENTRY(AVX512VL) \ + DN_CPU_FEAT_XENTRY(AVX512VBMI) \ + DN_CPU_FEAT_XENTRY(AVX512VBMI2) \ + DN_CPU_FEAT_XENTRY(AVX512VNNI) \ + DN_CPU_FEAT_XENTRY(AVX512BITALG) \ + DN_CPU_FEAT_XENTRY(AVX512VPOPCNTDQ) \ + DN_CPU_FEAT_XENTRY(AVX5124VNNIW) \ + DN_CPU_FEAT_XENTRY(AVX5124FMAPS) \ + DN_CPU_FEAT_XENTRY(AVX512VP2INTERSECT) \ + DN_CPU_FEAT_XENTRY(AVX512FP16) \ + DN_CPU_FEAT_XENTRY(CLZERO) \ + DN_CPU_FEAT_XENTRY(CMPXCHG8B) \ + DN_CPU_FEAT_XENTRY(CMPXCHG16B) \ + DN_CPU_FEAT_XENTRY(F16C) \ + DN_CPU_FEAT_XENTRY(FMA) \ + DN_CPU_FEAT_XENTRY(FMA4) \ + DN_CPU_FEAT_XENTRY(FP128) \ + DN_CPU_FEAT_XENTRY(FP256) \ + DN_CPU_FEAT_XENTRY(FPU) \ + DN_CPU_FEAT_XENTRY(MMX) \ + DN_CPU_FEAT_XENTRY(MONITOR) \ + DN_CPU_FEAT_XENTRY(MOVBE) \ + DN_CPU_FEAT_XENTRY(MOVU) \ + DN_CPU_FEAT_XENTRY(MmxExt) \ + DN_CPU_FEAT_XENTRY(PCLMULQDQ) \ + DN_CPU_FEAT_XENTRY(POPCNT) \ + DN_CPU_FEAT_XENTRY(RDRAND) \ + DN_CPU_FEAT_XENTRY(RDSEED) \ + DN_CPU_FEAT_XENTRY(RDTSCP) \ + DN_CPU_FEAT_XENTRY(SHA) \ + DN_CPU_FEAT_XENTRY(SSE) \ + DN_CPU_FEAT_XENTRY(SSE2) \ + DN_CPU_FEAT_XENTRY(SSE3) \ + DN_CPU_FEAT_XENTRY(SSE41) \ + DN_CPU_FEAT_XENTRY(SSE42) \ + DN_CPU_FEAT_XENTRY(SSE4A) \ + DN_CPU_FEAT_XENTRY(SSSE3) \ + DN_CPU_FEAT_XENTRY(TSC) \ + DN_CPU_FEAT_XENTRY(TscInvariant) \ + DN_CPU_FEAT_XENTRY(VAES) \ + DN_CPU_FEAT_XENTRY(VPCMULQDQ) + +enum DN_CPUFeature +{ + #define DN_CPU_FEAT_XENTRY(label) DN_CPUFeature_##label, + DN_CPU_FEAT_XMACRO + #undef DN_CPU_FEAT_XENTRY + DN_CPUFeature_Count, +}; + +struct DN_CPUFeatureDecl +{ + DN_CPUFeature value; + DN_Str8 label; +}; + +struct DN_CPUFeatureQuery +{ + DN_CPUFeature feature; + bool available; +}; + +struct DN_CPUReport +{ + char vendor[4 /*bytes*/ * 3 /*EDX, ECX, EBX*/ + 1 /*null*/]; + char brand[48]; + DN_U64 features[(DN_CPUFeature_Count / (sizeof(DN_U64) * 8)) + 1]; +}; + +struct DN_TicketMutex +{ + unsigned int volatile ticket; // The next ticket to give out to the thread taking the mutex + unsigned int volatile serving; // The ticket ID to block the mutex on until it is returned +}; + +struct DN_U64FromResult +{ + bool success; + DN_U64 value; +}; + +struct DN_I64FromResult +{ + bool success; + DN_I64 value; +}; + +enum DN_MemCommit +{ + DN_MemCommit_No, + DN_MemCommit_Yes, +}; + +typedef DN_U32 DN_MemPage; +enum DN_MemPage_ +{ + // Exception on read/write with a page. This flag overrides the read/write + // access. + DN_MemPage_NoAccess = 1 << 0, + + DN_MemPage_Read = 1 << 1, // Only read permitted on the page. + + // Only write permitted on the page. On Windows this is not supported and + // will be promoted to read+write permissions. + DN_MemPage_Write = 1 << 2, + + DN_MemPage_ReadWrite = DN_MemPage_Read | DN_MemPage_Write, + + // Modifier used in conjunction with previous flags. Raises exception on + // first access to the page, then, the underlying protection flags are + // active. This is supported on Windows, on other OS's using this flag will + // set the OS equivalent of DN_MemPage_NoAccess. + // This flag must only be used in DN_Mem_Protect + DN_MemPage_Guard = 1 << 3, + + // If leak tracing is enabled, this flag will allow the allocation recorded + // from the reserve call to be leaked, e.g. not printed when leaks are + // dumped to the console. + DN_MemPage_AllocRecordLeakPermitted = 1 << 4, + + // If leak tracing is enabled this flag will prevent any allocation record + // from being created in the allocation table at all. If this flag is + // enabled, 'OSMemPage_AllocRecordLeakPermitted' has no effect since the + // record will never be created. + DN_MemPage_NoAllocRecordEntry = 1 << 5, + + // [INTERNAL] Do not use. All flags together do not constitute a correct + // configuration of pages. + DN_MemPage_All = DN_MemPage_NoAccess | + DN_MemPage_ReadWrite | + DN_MemPage_Guard | + DN_MemPage_AllocRecordLeakPermitted | + DN_MemPage_NoAllocRecordEntry, +}; + +#if !defined(DN_ARENA_RESERVE_SIZE) + #define DN_ARENA_RESERVE_SIZE DN_Megabytes(64) +#endif + +#if !defined(DN_ARENA_COMMIT_SIZE) + #define DN_ARENA_COMMIT_SIZE DN_Kilobytes(64) +#endif + +enum DN_Allocator +{ + DN_Allocator_Arena, + DN_Allocator_Pool, +}; + +struct DN_ArenaBlock +{ + DN_ArenaBlock *prev; + DN_U64 used; + DN_U64 commit; + DN_U64 reserve; + DN_U64 reserve_sum; +}; + +typedef DN_U32 DN_ArenaFlags; +enum DN_ArenaFlags_ +{ + DN_ArenaFlags_Nil = 0, + DN_ArenaFlags_NoGrow = 1 << 0, + DN_ArenaFlags_NoPoison = 1 << 1, + DN_ArenaFlags_NoAllocTrack = 1 << 2, + DN_ArenaFlags_AllocCanLeak = 1 << 3, + + // NOTE: Internal flags. Do not use + DN_ArenaFlags_UserBuffer = 1 << 4, + DN_ArenaFlags_MemFuncs = 1 << 5, +}; + +struct DN_ArenaInfo +{ + DN_U64 used; + DN_U64 commit; + DN_U64 reserve; + DN_U64 blocks; +}; + +struct DN_ArenaStats +{ + DN_ArenaInfo info; + DN_ArenaInfo hwm; +}; + +struct DN_ArenaStatsStr8x64 +{ + DN_Str8x64 info; + DN_Str8x64 hwm; +}; + +enum DN_ArenaMemFuncType +{ + DN_ArenaMemFuncType_Nil, + DN_ArenaMemFuncType_Basic, + DN_ArenaMemFuncType_VMem, +}; + +typedef void *(DN_ArenaMemBasicAllocFunc)(DN_USize size); +typedef void (DN_ArenaMemBasicDeallocFunc)(void *ptr); +typedef void *(DN_ArenaMemVMemReserveFunc)(DN_USize size, DN_MemCommit commit, DN_MemPage page_flags); +typedef bool (DN_ArenaMemVMemCommitFunc)(void *ptr, DN_USize size, DN_U32 page_flags); +typedef void (DN_ArenaMemVMemReleaseFunc)(void *ptr, DN_USize size); +struct DN_ArenaMemFuncs +{ + DN_ArenaMemFuncType type; + DN_ArenaMemBasicAllocFunc *basic_alloc; + DN_ArenaMemBasicDeallocFunc *basic_dealloc; + + DN_U32 vmem_page_size; + DN_ArenaMemVMemReserveFunc *vmem_reserve; + DN_ArenaMemVMemCommitFunc *vmem_commit; + DN_ArenaMemVMemReleaseFunc *vmem_release; +}; + +struct DN_Arena +{ + DN_ArenaMemFuncs mem_funcs; + DN_ArenaBlock *curr; + DN_ArenaStats stats; + DN_ArenaFlags flags; + DN_Str8 label; + DN_Arena *prev, *next; +}; + +struct DN_ArenaTempMem +{ + DN_Arena *arena; + DN_U64 used_sum; +}; + +struct DN_ArenaTempMemScope +{ + DN_ArenaTempMemScope(DN_Arena *arena); + ~DN_ArenaTempMemScope(); + DN_ArenaTempMem mem; +}; + +DN_USize const DN_ARENA_HEADER_SIZE = DN_AlignUpPowerOfTwo(sizeof(DN_Arena), 64); + +#if !defined(DN_POOL_DEFAULT_ALIGN) + #define DN_POOL_DEFAULT_ALIGN 16 +#endif + +struct DN_PoolSlot +{ + void *data; + DN_PoolSlot *next; +}; + +enum DN_PoolSlotSize +{ + DN_PoolSlotSize_32B, + DN_PoolSlotSize_64B, + DN_PoolSlotSize_128B, + DN_PoolSlotSize_256B, + DN_PoolSlotSize_512B, + DN_PoolSlotSize_1KiB, + DN_PoolSlotSize_2KiB, + DN_PoolSlotSize_4KiB, + DN_PoolSlotSize_8KiB, + DN_PoolSlotSize_16KiB, + DN_PoolSlotSize_32KiB, + DN_PoolSlotSize_64KiB, + DN_PoolSlotSize_128KiB, + DN_PoolSlotSize_256KiB, + DN_PoolSlotSize_512KiB, + DN_PoolSlotSize_1MiB, + DN_PoolSlotSize_2MiB, + DN_PoolSlotSize_4MiB, + DN_PoolSlotSize_8MiB, + DN_PoolSlotSize_16MiB, + DN_PoolSlotSize_32MiB, + DN_PoolSlotSize_64MiB, + DN_PoolSlotSize_128MiB, + DN_PoolSlotSize_256MiB, + DN_PoolSlotSize_512MiB, + DN_PoolSlotSize_1GiB, + DN_PoolSlotSize_2GiB, + DN_PoolSlotSize_4GiB, + DN_PoolSlotSize_8GiB, + DN_PoolSlotSize_16GiB, + DN_PoolSlotSize_32GiB, + DN_PoolSlotSize_Count, +}; + +struct DN_Pool +{ + DN_Arena *arena; + DN_PoolSlot *slots[DN_PoolSlotSize_Count]; + DN_U8 align; +}; + +struct DN_NibbleFromU8Result +{ + char nibble0; + char nibble1; +}; + +enum DN_Str8EqCase +{ + DN_Str8EqCase_Sensitive, + DN_Str8EqCase_Insensitive, +}; + +enum DN_Str8IsAllType +{ + DN_Str8IsAllType_Digits, + DN_Str8IsAllType_Hex, +}; + +struct DN_Str8BSplitResult +{ + DN_Str8 lhs; + DN_Str8 rhs; +}; + +struct DN_Str8FindResult +{ + bool found; // True if string was found. If false, the subsequent fields below are not set. + DN_USize index; // Index in the buffer where the found string starts + DN_Str8 match; // Matching string in the buffer that was searched + DN_Str8 match_to_end_of_buffer; // Substring containing the found string to the end of the buffer + DN_Str8 after_match_to_end_of_buffer; // Substring starting after the found string to the end of the buffer + DN_Str8 start_to_before_match; // Substring from the start of the buffer up until the found string, not including it +}; + +enum DN_Str8FindFlag +{ + DN_Str8FindFlag_Digit = 1 << 0, // 0-9 + DN_Str8FindFlag_Whitespace = 1 << 1, // '\r', '\t', '\n', ' ' + DN_Str8FindFlag_Alphabet = 1 << 2, // A-Z, a-z + DN_Str8FindFlag_Plus = 1 << 3, // + + DN_Str8FindFlag_Minus = 1 << 4, // - + DN_Str8FindFlag_AlphaNum = DN_Str8FindFlag_Alphabet | DN_Str8FindFlag_Digit, +}; + +enum DN_Str8SplitIncludeEmptyStrings +{ + DN_Str8SplitIncludeEmptyStrings_No, + DN_Str8SplitIncludeEmptyStrings_Yes, +}; + +struct DN_Str8TruncateResult +{ + bool truncated; + DN_Str8 str8; +}; + +struct DN_Str8SplitResult +{ + DN_Str8 *data; + DN_USize count; +}; + +struct DN_Str8Link +{ + DN_Str8 string; // The string + DN_Str8Link *next; // The next string in the linked list + DN_Str8Link *prev; // The prev string in the linked list +}; + +struct DN_Str8Builder +{ + DN_Arena *arena; // Allocator to use to back the string list + DN_Str8Link *head; // First string in the linked list of strings + DN_Str8Link *tail; // Last string in the linked list of strings + DN_USize string_size; // The size in bytes necessary to construct the current string + DN_USize count; // The number of links in the linked list of strings +}; + +enum DN_Str8BuilderAdd +{ + DN_Str8BuilderAdd_Append, + DN_Str8BuilderAdd_Prepend, +}; + +typedef DN_U32 DN_AgeUnit; +enum DN_AgeUnit_ +{ + DN_AgeUnit_Ms = 1 << 0, + DN_AgeUnit_Sec = 1 << 1, + DN_AgeUnit_Min = 1 << 2, + DN_AgeUnit_Hr = 1 << 3, + DN_AgeUnit_Day = 1 << 4, + DN_AgeUnit_Week = 1 << 5, + DN_AgeUnit_Year = 1 << 6, + DN_AgeUnit_FractionalSec = 1 << 7, + DN_AgeUnit_HMS = DN_AgeUnit_Sec | DN_AgeUnit_Min | DN_AgeUnit_Hr, + DN_AgeUnit_All = DN_AgeUnit_Ms | DN_AgeUnit_HMS | DN_AgeUnit_Day | DN_AgeUnit_Week | DN_AgeUnit_Year, +}; + +enum DN_ByteCountType +{ + DN_ByteCountType_B, + DN_ByteCountType_KiB, + DN_ByteCountType_MiB, + DN_ByteCountType_GiB, + DN_ByteCountType_TiB, + DN_ByteCountType_Count, + DN_ByteCountType_Auto, +}; + +struct DN_ByteCountResult +{ + DN_ByteCountType type; + DN_Str8 suffix; // "KiB", "MiB", "GiB" .. e.t.c + DN_F64 bytes; +}; + +struct DN_FmtAppendResult +{ + DN_USize size_req; + DN_Str8 str8; + bool truncated; +}; + +struct DN_ProfilerAnchor +{ + // Inclusive refers to the time spent to complete the function call + // including all children functions. + // + // Exclusive refers to the time spent in the function, not including any + // time spent in children functions that we call that are also being + // profiled. If we recursively call into ourselves, the time we spent in + // our function is accumulated. + DN_U64 tsc_inclusive; + DN_U64 tsc_exclusive; + DN_U16 hit_count; + DN_Str8 name; +}; + +struct DN_ProfilerZone +{ + DN_U16 anchor_index; + DN_U64 begin_tsc; + DN_U16 parent_zone; + DN_U64 elapsed_tsc_at_zone_start; +}; + +struct DN_ProfilerAnchorArray +{ + DN_ProfilerAnchor *data; + DN_USize count; +}; + +typedef DN_U64 (DN_ProfilerTSCNowFunc)(); +struct DN_Profiler +{ + DN_USize frame_index; + DN_ProfilerAnchor *anchors; + DN_USize anchors_count; + DN_USize anchors_per_frame; + DN_U16 parent_zone; + bool paused; + DN_ProfilerTSCNowFunc *tsc_now; + DN_U64 tsc_frequency; + DN_ProfilerZone frame_zone; + DN_F64 frame_avg_tsc; +}; + +#if !defined(DN_STB_SPRINTF_HEADER_ONLY) + #define STB_SPRINTF_IMPLEMENTATION + #define STB_SPRINTF_STATIC +#endif + +DN_MSVC_WARNING_PUSH +DN_MSVC_WARNING_DISABLE(4505) // Unused function warning +DN_GCC_WARNING_PUSH +DN_GCC_WARNING_DISABLE(-Wunused-function) +// DN: Single header generator commented out this header => #include "../External/stb_sprintf.h" +// NOTE: Additional *unofficial* changes +// - Adding STBSP__ASAN to STBSP__PUBLICDEC so that MSVC's ASAN does not trigger (https://github.com/nothings/stb/pull/1350) +// - Adding __attribute__((no_sanitize("undefined"))) to STBSP__ASAN for CLANG so that UBSAN does not trigger (https://github.com/nothings/stb/pull/1477) +// - Adding '%S' for DN_Str8 +// - Using defined(__wasm64__) to correctly assign stbsp__uintptr to stbsp__uint64 for a 64bit WASM target. + +// stb_sprintf - v1.10 - public domain snprintf() implementation +// originally by Jeff Roberts / RAD Game Tools, 2015/10/20 +// http://github.com/nothings/stb +// +// allowed types: sc uidBboXx p AaGgEef n +// lengths : hh h ll j z t I64 I32 I +// +// Contributors: +// Fabian "ryg" Giesen (reformatting) +// github:aganm (attribute format) +// +// Contributors (bugfixes): +// github:d26435 +// github:trex78 +// github:account-login +// Jari Komppa (SI suffixes) +// Rohit Nirmal +// Marcin Wojdyr +// Leonard Ritter +// Stefano Zanotti +// Adam Allison +// Arvid Gerstmann +// Markus Kolb +// +// LICENSE: +// +// See end of file for license information. + +#ifndef STB_SPRINTF_H_INCLUDE +#define STB_SPRINTF_H_INCLUDE + +/* +Single file sprintf replacement. + +Originally written by Jeff Roberts at RAD Game Tools - 2015/10/20. +Hereby placed in public domain. + +This is a full sprintf replacement that supports everything that +the C runtime sprintfs support, including float/double, 64-bit integers, +hex floats, field parameters (%*.*d stuff), length reads backs, etc. + +Why would you need this if sprintf already exists? Well, first off, +it's *much* faster (see below). It's also much smaller than the CRT +versions code-space-wise. We've also added some simple improvements +that are super handy (commas in thousands, callbacks at buffer full, +for example). Finally, the format strings for MSVC and GCC differ +for 64-bit integers (among other small things), so this lets you use +the same format strings in cross platform code. + +It uses the standard single file trick of being both the header file +and the source itself. If you just include it normally, you just get +the header file function definitions. To get the code, you include +it from a C or C++ file and define STB_SPRINTF_IMPLEMENTATION first. + +It only uses va_args macros from the C runtime to do it's work. It +does cast doubles to S64s and shifts and divides U64s, which does +drag in CRT code on most platforms. + +It compiles to roughly 8K with float support, and 4K without. +As a comparison, when using MSVC static libs, calling sprintf drags +in 16K. + +API: +==== +int stbsp_sprintf( char * buf, char const * fmt, ... ) +int stbsp_snprintf( char * buf, int count, char const * fmt, ... ) + Convert an arg list into a buffer. stbsp_snprintf always returns + a zero-terminated string (unlike regular snprintf). + +int stbsp_vsprintf( char * buf, char const * fmt, va_list va ) +int stbsp_vsnprintf( char * buf, int count, char const * fmt, va_list va ) + Convert a va_list arg list into a buffer. stbsp_vsnprintf always returns + a zero-terminated string (unlike regular snprintf). + +int stbsp_vsprintfcb( STBSP_SPRINTFCB * callback, void * user, char * buf, char const * fmt, va_list va ) + typedef char * STBSP_SPRINTFCB( char const * buf, void * user, int len ); + Convert into a buffer, calling back every STB_SPRINTF_MIN chars. + Your callback can then copy the chars out, print them or whatever. + This function is actually the workhorse for everything else. + The buffer you pass in must hold at least STB_SPRINTF_MIN characters. + // you return the next buffer to use or 0 to stop converting + +void stbsp_set_separators( char comma, char period ) + Set the comma and period characters to use. + +FLOATS/DOUBLES: +=============== +This code uses a internal float->ascii conversion method that uses +doubles with error correction (double-doubles, for ~105 bits of +precision). This conversion is round-trip perfect - that is, an atof +of the values output here will give you the bit-exact double back. + +One difference is that our insignificant digits will be different than +with MSVC or GCC (but they don't match each other either). We also +don't attempt to find the minimum length matching float (pre-MSVC15 +doesn't either). + +If you don't need float or doubles at all, define STB_SPRINTF_NOFLOAT +and you'll save 4K of code space. + +64-BIT INTS: +============ +This library also supports 64-bit integers and you can use MSVC style or +GCC style indicators (%I64d or %lld). It supports the C99 specifiers +for size_t and ptr_diff_t (%jd %zd) as well. + +EXTRAS: +======= +Like some GCCs, for integers and floats, you can use a ' (single quote) +specifier and commas will be inserted on the thousands: "%'d" on 12345 +would print 12,345. + +For integers and floats, you can use a "$" specifier and the number +will be converted to float and then divided to get kilo, mega, giga or +tera and then printed, so "%$d" 1000 is "1.0 k", "%$.2d" 2536000 is +"2.53 M", etc. For byte values, use two $:s, like "%$$d" to turn +2536000 to "2.42 Mi". If you prefer JEDEC suffixes to SI ones, use three +$:s: "%$$$d" -> "2.42 M". To remove the space between the number and the +suffix, add "_" specifier: "%_$d" -> "2.53M". + +In addition to octal and hexadecimal conversions, you can print +integers in binary: "%b" for 256 would print 100. + +PERFORMANCE vs MSVC 2008 32-/64-bit (GCC is even slower than MSVC): +=================================================================== +"%d" across all 32-bit ints (4.8x/4.0x faster than 32-/64-bit MSVC) +"%24d" across all 32-bit ints (4.5x/4.2x faster) +"%x" across all 32-bit ints (4.5x/3.8x faster) +"%08x" across all 32-bit ints (4.3x/3.8x faster) +"%f" across e-10 to e+10 floats (7.3x/6.0x faster) +"%e" across e-10 to e+10 floats (8.1x/6.0x faster) +"%g" across e-10 to e+10 floats (10.0x/7.1x faster) +"%f" for values near e-300 (7.9x/6.5x faster) +"%f" for values near e+300 (10.0x/9.1x faster) +"%e" for values near e-300 (10.1x/7.0x faster) +"%e" for values near e+300 (9.2x/6.0x faster) +"%.320f" for values near e-300 (12.6x/11.2x faster) +"%a" for random values (8.6x/4.3x faster) +"%I64d" for 64-bits with 32-bit values (4.8x/3.4x faster) +"%I64d" for 64-bits > 32-bit values (4.9x/5.5x faster) +"%s%s%s" for 64 char strings (7.1x/7.3x faster) +"...512 char string..." ( 35.0x/32.5x faster!) +*/ + +#if defined(__clang__) + #if defined(__has_feature) && defined(__has_attribute) + #if __has_feature(address_sanitizer) + #if __has_attribute(__no_sanitize__) + #define STBSP__ASAN __attribute__((__no_sanitize__("address"))) + #elif __has_attribute(__no_sanitize_address__) + #define STBSP__ASAN __attribute__((__no_sanitize_address__)) + #elif __has_attribute(__no_address_safety_analysis__) + #define STBSP__ASAN __attribute__((__no_address_safety_analysis__)) + #endif + #endif + #endif +#elif defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) + #if defined(__SANITIZE_ADDRESS__) && __SANITIZE_ADDRESS__ + #define STBSP__ASAN __attribute__((__no_sanitize_address__)) + #endif +#elif defined(_MSC_VER) + #if defined(__SANITIZE_ADDRESS__) + #define STBSP__ASAN __declspec(no_sanitize_address) + #endif +#endif + +#ifndef STBSP__ASAN +#define STBSP__ASAN +#endif + +#ifdef STB_SPRINTF_STATIC +#define STBSP__PUBLICDEC static STBSP__ASAN +#define STBSP__PUBLICDEF static STBSP__ASAN +#else +#ifdef __cplusplus +#define STBSP__PUBLICDEC extern "C" STBSP__ASAN +#define STBSP__PUBLICDEF extern "C" STBSP__ASAN +#else +#define STBSP__PUBLICDEC extern STBSP__ASAN +#define STBSP__PUBLICDEF STBSP__ASAN +#endif +#endif + +#if defined(__has_attribute) + #if __has_attribute(format) + #define STBSP__ATTRIBUTE_FORMAT(fmt,va) __attribute__((format(printf,fmt,va))) + #endif +#endif + +#ifndef STBSP__ATTRIBUTE_FORMAT +#define STBSP__ATTRIBUTE_FORMAT(fmt,va) +#endif + +#ifdef _MSC_VER +#define STBSP__NOTUSED(v) (void)(v) +#else +#define STBSP__NOTUSED(v) (void)sizeof(v) +#endif + +#include // for va_arg(), va_list() +#include // size_t, ptrdiff_t + +#ifndef STB_SPRINTF_MIN +#define STB_SPRINTF_MIN 512 // how many characters per callback +#endif +typedef char *STBSP_SPRINTFCB(const char *buf, void *user, int len); + +#ifndef STB_SPRINTF_DECORATE +#define STB_SPRINTF_DECORATE(name) stbsp_##name // define this before including if you want to change the names +#endif + +STBSP__PUBLICDEC int STB_SPRINTF_DECORATE(vsprintf)(char *buf, char const *fmt, va_list va); +STBSP__PUBLICDEC int STB_SPRINTF_DECORATE(vsnprintf)(char *buf, int count, char const *fmt, va_list va); +STBSP__PUBLICDEC int STB_SPRINTF_DECORATE(sprintf)(char *buf, char const *fmt, ...) STBSP__ATTRIBUTE_FORMAT(2,3); +STBSP__PUBLICDEC int STB_SPRINTF_DECORATE(snprintf)(char *buf, int count, char const *fmt, ...) STBSP__ATTRIBUTE_FORMAT(3,4); + +STBSP__PUBLICDEC int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback, void *user, char *buf, char const *fmt, va_list va); +STBSP__PUBLICDEC void STB_SPRINTF_DECORATE(set_separators)(char comma, char period); + +#endif // STB_SPRINTF_H_INCLUDE + +#ifdef STB_SPRINTF_IMPLEMENTATION + +#define stbsp__uint32 unsigned int +#define stbsp__int32 signed int + +#ifdef _MSC_VER +#define stbsp__uint64 unsigned __int64 +#define stbsp__int64 signed __int64 +#else +#define stbsp__uint64 unsigned long long +#define stbsp__int64 signed long long +#endif +#define stbsp__uint16 unsigned short + +#ifndef stbsp__uintptr +#if defined(__ppc64__) || defined(__powerpc64__) || defined(__aarch64__) || defined(_M_X64) || defined(__x86_64__) || defined(__x86_64) || defined(__s390x__) || defined(__wasm64__) +#define stbsp__uintptr stbsp__uint64 +#else +#define stbsp__uintptr stbsp__uint32 +#endif +#endif + +#ifndef STB_SPRINTF_MSVC_MODE // used for MSVC2013 and earlier (MSVC2015 matches GCC) +#if defined(_MSC_VER) && (_MSC_VER < 1900) +#define STB_SPRINTF_MSVC_MODE +#endif +#endif + +#ifdef STB_SPRINTF_NOUNALIGNED // define this before inclusion to force stbsp_sprintf to always use aligned accesses +#define STBSP__UNALIGNED(code) +#else +#define STBSP__UNALIGNED(code) code +#endif + +#ifndef STB_SPRINTF_NOFLOAT +// internal float utility functions +static stbsp__int32 stbsp__real_to_str(char const **start, stbsp__uint32 *len, char *out, stbsp__int32 *decimal_pos, double value, stbsp__uint32 frac_digits); +static stbsp__int32 stbsp__real_to_parts(stbsp__int64 *bits, stbsp__int32 *expo, double value); +#define STBSP__SPECIAL 0x7000 +#endif + +static char stbsp__period = '.'; +static char stbsp__comma = ','; +static struct +{ + short temp; // force next field to be 2-byte aligned + char pair[201]; +} stbsp__digitpair = +{ + 0, + "00010203040506070809101112131415161718192021222324" + "25262728293031323334353637383940414243444546474849" + "50515253545556575859606162636465666768697071727374" + "75767778798081828384858687888990919293949596979899" +}; + +STBSP__PUBLICDEF void STB_SPRINTF_DECORATE(set_separators)(char pcomma, char pperiod) +{ + stbsp__period = pperiod; + stbsp__comma = pcomma; +} + +#define STBSP__LEFTJUST 1 +#define STBSP__LEADINGPLUS 2 +#define STBSP__LEADINGSPACE 4 +#define STBSP__LEADING_0X 8 +#define STBSP__LEADINGZERO 16 +#define STBSP__INTMAX 32 +#define STBSP__TRIPLET_COMMA 64 +#define STBSP__NEGATIVE 128 +#define STBSP__METRIC_SUFFIX 256 +#define STBSP__HALFWIDTH 512 +#define STBSP__METRIC_NOSPACE 1024 +#define STBSP__METRIC_1024 2048 +#define STBSP__METRIC_JEDEC 4096 + +static void stbsp__lead_sign(stbsp__uint32 fl, char *sign) +{ + sign[0] = 0; + if (fl & STBSP__NEGATIVE) { + sign[0] = 1; + sign[1] = '-'; + } else if (fl & STBSP__LEADINGSPACE) { + sign[0] = 1; + sign[1] = ' '; + } else if (fl & STBSP__LEADINGPLUS) { + sign[0] = 1; + sign[1] = '+'; + } +} + +static STBSP__ASAN stbsp__uint32 stbsp__strlen_limited(char const *s, stbsp__uint32 limit) +{ + char const * sn = s; + + // get up to 4-byte alignment + for (;;) { + if (((stbsp__uintptr)sn & 3) == 0) + break; + + if (!limit || *sn == 0) + return (stbsp__uint32)(sn - s); + + ++sn; + --limit; + } + + // scan over 4 bytes at a time to find terminating 0 + // this will intentionally scan up to 3 bytes past the end of buffers, + // but becase it works 4B aligned, it will never cross page boundaries + // (hence the STBSP__ASAN markup; the over-read here is intentional + // and harmless) + while (limit >= 4) { + stbsp__uint32 v = *(stbsp__uint32 *)sn; + // bit hack to find if there's a 0 byte in there + if ((v - 0x01010101) & (~v) & 0x80808080UL) + break; + + sn += 4; + limit -= 4; + } + + // handle the last few characters to find actual size + while (limit && *sn) { + ++sn; + --limit; + } + + return (stbsp__uint32)(sn - s); +} + +STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback, void *user, char *buf, char const *fmt, va_list va) +{ + static char hex[] = "0123456789abcdefxp"; + static char hexu[] = "0123456789ABCDEFXP"; + char *bf; + char const *f; + int tlen = 0; + + bf = buf; + f = fmt; + for (;;) { + stbsp__int32 fw, pr, tz; + stbsp__uint32 fl; + + // macros for the callback buffer stuff + #define stbsp__chk_cb_bufL(bytes) \ + { \ + int len = (int)(bf - buf); \ + if ((len + (bytes)) >= STB_SPRINTF_MIN) { \ + tlen += len; \ + if (0 == (bf = buf = callback(buf, user, len))) \ + goto done; \ + } \ + } + #define stbsp__chk_cb_buf(bytes) \ + { \ + if (callback) { \ + stbsp__chk_cb_bufL(bytes); \ + } \ + } + #define stbsp__flush_cb() \ + { \ + stbsp__chk_cb_bufL(STB_SPRINTF_MIN - 1); \ + } // flush if there is even one byte in the buffer + #define stbsp__cb_buf_clamp(cl, v) \ + cl = v; \ + if (callback) { \ + int lg = STB_SPRINTF_MIN - (int)(bf - buf); \ + if (cl > lg) \ + cl = lg; \ + } + + // fast copy everything up to the next % (or end of string) + for (;;) { + while (((stbsp__uintptr)f) & 3) { + schk1: + if (f[0] == '%') + goto scandd; + schk2: + if (f[0] == 0) + goto endfmt; + stbsp__chk_cb_buf(1); + *bf++ = f[0]; + ++f; + } + for (;;) { + // Check if the next 4 bytes contain %(0x25) or end of string. + // Using the 'hasless' trick: + // https://graphics.stanford.edu/~seander/bithacks.html#HasLessInWord + stbsp__uint32 v, c; + v = *(stbsp__uint32 *)f; + c = (~v) & 0x80808080; + if (((v ^ 0x25252525) - 0x01010101) & c) + goto schk1; + if ((v - 0x01010101) & c) + goto schk2; + if (callback) + if ((STB_SPRINTF_MIN - (int)(bf - buf)) < 4) + goto schk1; + #ifdef STB_SPRINTF_NOUNALIGNED + if(((stbsp__uintptr)bf) & 3) { + bf[0] = f[0]; + bf[1] = f[1]; + bf[2] = f[2]; + bf[3] = f[3]; + } else + #endif + { + *(stbsp__uint32 *)bf = v; + } + bf += 4; + f += 4; + } + } + scandd: + + ++f; + + // ok, we have a percent, read the modifiers first + fw = 0; + pr = -1; + fl = 0; + tz = 0; + + // flags + for (;;) { + switch (f[0]) { + // if we have left justify + case '-': + fl |= STBSP__LEFTJUST; + ++f; + continue; + // if we have leading plus + case '+': + fl |= STBSP__LEADINGPLUS; + ++f; + continue; + // if we have leading space + case ' ': + fl |= STBSP__LEADINGSPACE; + ++f; + continue; + // if we have leading 0x + case '#': + fl |= STBSP__LEADING_0X; + ++f; + continue; + // if we have thousand commas + case '\'': + fl |= STBSP__TRIPLET_COMMA; + ++f; + continue; + // if we have kilo marker (none->kilo->kibi->jedec) + case '$': + if (fl & STBSP__METRIC_SUFFIX) { + if (fl & STBSP__METRIC_1024) { + fl |= STBSP__METRIC_JEDEC; + } else { + fl |= STBSP__METRIC_1024; + } + } else { + fl |= STBSP__METRIC_SUFFIX; + } + ++f; + continue; + // if we don't want space between metric suffix and number + case '_': + fl |= STBSP__METRIC_NOSPACE; + ++f; + continue; + // if we have leading zero + case '0': + fl |= STBSP__LEADINGZERO; + ++f; + goto flags_done; + default: goto flags_done; + } + } + flags_done: + + // get the field width + if (f[0] == '*') { + fw = va_arg(va, stbsp__uint32); + ++f; + } else { + while ((f[0] >= '0') && (f[0] <= '9')) { + fw = fw * 10 + f[0] - '0'; + f++; + } + } + // get the precision + if (f[0] == '.') { + ++f; + if (f[0] == '*') { + pr = va_arg(va, stbsp__uint32); + ++f; + } else { + pr = 0; + while ((f[0] >= '0') && (f[0] <= '9')) { + pr = pr * 10 + f[0] - '0'; + f++; + } + } + } + + // handle integer size overrides + switch (f[0]) { + // are we halfwidth? + case 'h': + fl |= STBSP__HALFWIDTH; + ++f; + if (f[0] == 'h') + ++f; // QUARTERWIDTH + break; + // are we 64-bit (unix style) + case 'l': + fl |= ((sizeof(long) == 8) ? STBSP__INTMAX : 0); + ++f; + if (f[0] == 'l') { + fl |= STBSP__INTMAX; + ++f; + } + break; + // are we 64-bit on intmax? (c99) + case 'j': + fl |= (sizeof(size_t) == 8) ? STBSP__INTMAX : 0; + ++f; + break; + // are we 64-bit on size_t or ptrdiff_t? (c99) + case 'z': + fl |= (sizeof(ptrdiff_t) == 8) ? STBSP__INTMAX : 0; + ++f; + break; + case 't': + fl |= (sizeof(ptrdiff_t) == 8) ? STBSP__INTMAX : 0; + ++f; + break; + // are we 64-bit (msft style) + case 'I': + if ((f[1] == '6') && (f[2] == '4')) { + fl |= STBSP__INTMAX; + f += 3; + } else if ((f[1] == '3') && (f[2] == '2')) { + f += 3; + } else { + fl |= ((sizeof(void *) == 8) ? STBSP__INTMAX : 0); + ++f; + } + break; + default: break; + } + + // handle each replacement + switch (f[0]) { + #define STBSP__NUMSZ 512 // big enough for e308 (with commas) or e-307 + char num[STBSP__NUMSZ]; + char lead[8]; + char tail[8]; + char *s; + char const *h; + stbsp__uint32 l, n, cs; + stbsp__uint64 n64; +#ifndef STB_SPRINTF_NOFLOAT + double fv; +#endif + stbsp__int32 dp; + char const *sn; + + case 's': + // get the string + s = va_arg(va, char *); + if (s == 0) + s = (char *)"null"; + // get the length, limited to desired precision + // always limit to ~0u chars since our counts are 32b + l = stbsp__strlen_limited(s, (pr >= 0) ? pr : ~0u); + lead[0] = 0; + tail[0] = 0; + pr = 0; + dp = 0; + cs = 0; + // copy the string in + goto scopy; + + case 'S': + { + DN_Str8 str8 = va_arg(va, DN_Str8); + s = (char *)str8.data; + l = (uint32_t)str8.size; + lead[0] = 0; + tail[0] = 0; + pr = 0; + dp = 0; + cs = 0; + }goto scopy; + + case 'c': // char + // get the character + s = num + STBSP__NUMSZ - 1; + *s = (char)va_arg(va, int); + l = 1; + lead[0] = 0; + tail[0] = 0; + pr = 0; + dp = 0; + cs = 0; + goto scopy; + + case 'n': // weird write-bytes specifier + { + int *d = va_arg(va, int *); + *d = tlen + (int)(bf - buf); + } break; + +#ifdef STB_SPRINTF_NOFLOAT + case 'A': // float + case 'a': // hex float + case 'G': // float + case 'g': // float + case 'E': // float + case 'e': // float + case 'f': // float + va_arg(va, double); // eat it + s = (char *)"No float"; + l = 8; + lead[0] = 0; + tail[0] = 0; + pr = 0; + cs = 0; + STBSP__NOTUSED(dp); + goto scopy; +#else + case 'A': // hex float + case 'a': // hex float + h = (f[0] == 'A') ? hexu : hex; + fv = va_arg(va, double); + if (pr == -1) + pr = 6; // default is 6 + // read the double into a string + if (stbsp__real_to_parts((stbsp__int64 *)&n64, &dp, fv)) + fl |= STBSP__NEGATIVE; + + s = num + 64; + + stbsp__lead_sign(fl, lead); + + if (dp == -1023) + dp = (n64) ? -1022 : 0; + else + n64 |= (((stbsp__uint64)1) << 52); + n64 <<= (64 - 56); + if (pr < 15) + n64 += ((((stbsp__uint64)8) << 56) >> (pr * 4)); +// add leading chars + +#ifdef STB_SPRINTF_MSVC_MODE + *s++ = '0'; + *s++ = 'x'; +#else + lead[1 + lead[0]] = '0'; + lead[2 + lead[0]] = 'x'; + lead[0] += 2; +#endif + *s++ = h[(n64 >> 60) & 15]; + n64 <<= 4; + if (pr) + *s++ = stbsp__period; + sn = s; + + // print the bits + n = pr; + if (n > 13) + n = 13; + if (pr > (stbsp__int32)n) + tz = pr - n; + pr = 0; + while (n--) { + *s++ = h[(n64 >> 60) & 15]; + n64 <<= 4; + } + + // print the expo + tail[1] = h[17]; + if (dp < 0) { + tail[2] = '-'; + dp = -dp; + } else + tail[2] = '+'; + n = (dp >= 1000) ? 6 : ((dp >= 100) ? 5 : ((dp >= 10) ? 4 : 3)); + tail[0] = (char)n; + for (;;) { + tail[n] = '0' + dp % 10; + if (n <= 3) + break; + --n; + dp /= 10; + } + + dp = (int)(s - sn); + l = (int)(s - (num + 64)); + s = num + 64; + cs = 1 + (3 << 24); + goto scopy; + + case 'G': // float + case 'g': // float + h = (f[0] == 'G') ? hexu : hex; + fv = va_arg(va, double); + if (pr == -1) + pr = 6; + else if (pr == 0) + pr = 1; // default is 6 + // read the double into a string + if (stbsp__real_to_str(&sn, &l, num, &dp, fv, (pr - 1) | 0x80000000)) + fl |= STBSP__NEGATIVE; + + // clamp the precision and delete extra zeros after clamp + n = pr; + if (l > (stbsp__uint32)pr) + l = pr; + while ((l > 1) && (pr) && (sn[l - 1] == '0')) { + --pr; + --l; + } + + // should we use %e + if ((dp <= -4) || (dp > (stbsp__int32)n)) { + if (pr > (stbsp__int32)l) + pr = l - 1; + else if (pr) + --pr; // when using %e, there is one digit before the decimal + goto doexpfromg; + } + // this is the insane action to get the pr to match %g semantics for %f + if (dp > 0) { + pr = (dp < (stbsp__int32)l) ? l - dp : 0; + } else { + pr = -dp + ((pr > (stbsp__int32)l) ? (stbsp__int32) l : pr); + } + goto dofloatfromg; + + case 'E': // float + case 'e': // float + h = (f[0] == 'E') ? hexu : hex; + fv = va_arg(va, double); + if (pr == -1) + pr = 6; // default is 6 + // read the double into a string + if (stbsp__real_to_str(&sn, &l, num, &dp, fv, pr | 0x80000000)) + fl |= STBSP__NEGATIVE; + doexpfromg: + tail[0] = 0; + stbsp__lead_sign(fl, lead); + if (dp == STBSP__SPECIAL) { + s = (char *)sn; + cs = 0; + pr = 0; + goto scopy; + } + s = num + 64; + // handle leading chars + *s++ = sn[0]; + + if (pr) + *s++ = stbsp__period; + + // handle after decimal + if ((l - 1) > (stbsp__uint32)pr) + l = pr + 1; + for (n = 1; n < l; n++) + *s++ = sn[n]; + // trailing zeros + tz = pr - (l - 1); + pr = 0; + // dump expo + tail[1] = h[0xe]; + dp -= 1; + if (dp < 0) { + tail[2] = '-'; + dp = -dp; + } else + tail[2] = '+'; +#ifdef STB_SPRINTF_MSVC_MODE + n = 5; +#else + n = (dp >= 100) ? 5 : 4; +#endif + tail[0] = (char)n; + for (;;) { + tail[n] = '0' + dp % 10; + if (n <= 3) + break; + --n; + dp /= 10; + } + cs = 1 + (3 << 24); // how many tens + goto flt_lead; + + case 'f': // float + fv = va_arg(va, double); + doafloat: + // do kilos + if (fl & STBSP__METRIC_SUFFIX) { + double divisor; + divisor = 1000.0f; + if (fl & STBSP__METRIC_1024) + divisor = 1024.0; + while (fl < 0x4000000) { + if ((fv < divisor) && (fv > -divisor)) + break; + fv /= divisor; + fl += 0x1000000; + } + } + if (pr == -1) + pr = 6; // default is 6 + // read the double into a string + if (stbsp__real_to_str(&sn, &l, num, &dp, fv, pr)) + fl |= STBSP__NEGATIVE; + dofloatfromg: + tail[0] = 0; + stbsp__lead_sign(fl, lead); + if (dp == STBSP__SPECIAL) { + s = (char *)sn; + cs = 0; + pr = 0; + goto scopy; + } + s = num + 64; + + // handle the three decimal varieties + if (dp <= 0) { + stbsp__int32 i; + // handle 0.000*000xxxx + *s++ = '0'; + if (pr) + *s++ = stbsp__period; + n = -dp; + if ((stbsp__int32)n > pr) + n = pr; + i = n; + while (i) { + if ((((stbsp__uintptr)s) & 3) == 0) + break; + *s++ = '0'; + --i; + } + while (i >= 4) { + *(stbsp__uint32 *)s = 0x30303030; + s += 4; + i -= 4; + } + while (i) { + *s++ = '0'; + --i; + } + if ((stbsp__int32)(l + n) > pr) + l = pr - n; + i = l; + while (i) { + *s++ = *sn++; + --i; + } + tz = pr - (n + l); + cs = 1 + (3 << 24); // how many tens did we write (for commas below) + } else { + cs = (fl & STBSP__TRIPLET_COMMA) ? ((600 - (stbsp__uint32)dp) % 3) : 0; + if ((stbsp__uint32)dp >= l) { + // handle xxxx000*000.0 + n = 0; + for (;;) { + if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) { + cs = 0; + *s++ = stbsp__comma; + } else { + *s++ = sn[n]; + ++n; + if (n >= l) + break; + } + } + if (n < (stbsp__uint32)dp) { + n = dp - n; + if ((fl & STBSP__TRIPLET_COMMA) == 0) { + while (n) { + if ((((stbsp__uintptr)s) & 3) == 0) + break; + *s++ = '0'; + --n; + } + while (n >= 4) { + *(stbsp__uint32 *)s = 0x30303030; + s += 4; + n -= 4; + } + } + while (n) { + if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) { + cs = 0; + *s++ = stbsp__comma; + } else { + *s++ = '0'; + --n; + } + } + } + cs = (int)(s - (num + 64)) + (3 << 24); // cs is how many tens + if (pr) { + *s++ = stbsp__period; + tz = pr; + } + } else { + // handle xxxxx.xxxx000*000 + n = 0; + for (;;) { + if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) { + cs = 0; + *s++ = stbsp__comma; + } else { + *s++ = sn[n]; + ++n; + if (n >= (stbsp__uint32)dp) + break; + } + } + cs = (int)(s - (num + 64)) + (3 << 24); // cs is how many tens + if (pr) + *s++ = stbsp__period; + if ((l - dp) > (stbsp__uint32)pr) + l = pr + dp; + while (n < l) { + *s++ = sn[n]; + ++n; + } + tz = pr - (l - dp); + } + } + pr = 0; + + // handle k,m,g,t + if (fl & STBSP__METRIC_SUFFIX) { + char idx; + idx = 1; + if (fl & STBSP__METRIC_NOSPACE) + idx = 0; + tail[0] = idx; + tail[1] = ' '; + { + if (fl >> 24) { // SI kilo is 'k', JEDEC and SI kibits are 'K'. + if (fl & STBSP__METRIC_1024) + tail[idx + 1] = "_KMGT"[fl >> 24]; + else + tail[idx + 1] = "_kMGT"[fl >> 24]; + idx++; + // If printing kibits and not in jedec, add the 'i'. + if (fl & STBSP__METRIC_1024 && !(fl & STBSP__METRIC_JEDEC)) { + tail[idx + 1] = 'i'; + idx++; + } + tail[0] = idx; + } + } + }; + + flt_lead: + // get the length that we copied + l = (stbsp__uint32)(s - (num + 64)); + s = num + 64; + goto scopy; +#endif + + case 'B': // upper binary + case 'b': // lower binary + h = (f[0] == 'B') ? hexu : hex; + lead[0] = 0; + if (fl & STBSP__LEADING_0X) { + lead[0] = 2; + lead[1] = '0'; + lead[2] = h[0xb]; + } + l = (8 << 4) | (1 << 8); + goto radixnum; + + case 'o': // octal + h = hexu; + lead[0] = 0; + if (fl & STBSP__LEADING_0X) { + lead[0] = 1; + lead[1] = '0'; + } + l = (3 << 4) | (3 << 8); + goto radixnum; + + case 'p': // pointer + fl |= (sizeof(void *) == 8) ? STBSP__INTMAX : 0; + pr = sizeof(void *) * 2; + fl &= ~STBSP__LEADINGZERO; // 'p' only prints the pointer with zeros + // fall through - to X + + case 'X': // upper hex + case 'x': // lower hex + h = (f[0] == 'X') ? hexu : hex; + l = (4 << 4) | (4 << 8); + lead[0] = 0; + if (fl & STBSP__LEADING_0X) { + lead[0] = 2; + lead[1] = '0'; + lead[2] = h[16]; + } + radixnum: + // get the number + if (fl & STBSP__INTMAX) + n64 = va_arg(va, stbsp__uint64); + else + n64 = va_arg(va, stbsp__uint32); + + s = num + STBSP__NUMSZ; + dp = 0; + // clear tail, and clear leading if value is zero + tail[0] = 0; + if (n64 == 0) { + lead[0] = 0; + if (pr == 0) { + l = 0; + cs = 0; + goto scopy; + } + } + // convert to string + for (;;) { + *--s = h[n64 & ((1 << (l >> 8)) - 1)]; + n64 >>= (l >> 8); + if (!((n64) || ((stbsp__int32)((num + STBSP__NUMSZ) - s) < pr))) + break; + if (fl & STBSP__TRIPLET_COMMA) { + ++l; + if ((l & 15) == ((l >> 4) & 15)) { + l &= ~15; + *--s = stbsp__comma; + } + } + }; + // get the tens and the comma pos + cs = (stbsp__uint32)((num + STBSP__NUMSZ) - s) + ((((l >> 4) & 15)) << 24); + // get the length that we copied + l = (stbsp__uint32)((num + STBSP__NUMSZ) - s); + // copy it + goto scopy; + + case 'u': // unsigned + case 'i': + case 'd': // integer + // get the integer and abs it + if (fl & STBSP__INTMAX) { + stbsp__int64 i64 = va_arg(va, stbsp__int64); + n64 = (stbsp__uint64)i64; + if ((f[0] != 'u') && (i64 < 0)) { + n64 = (stbsp__uint64)-i64; + fl |= STBSP__NEGATIVE; + } + } else { + stbsp__int32 i = va_arg(va, stbsp__int32); + n64 = (stbsp__uint32)i; + if ((f[0] != 'u') && (i < 0)) { + n64 = (stbsp__uint32)-i; + fl |= STBSP__NEGATIVE; + } + } + +#ifndef STB_SPRINTF_NOFLOAT + if (fl & STBSP__METRIC_SUFFIX) { + if (n64 < 1024) + pr = 0; + else if (pr == -1) + pr = 1; + fv = (double)(stbsp__int64)n64; + goto doafloat; + } +#endif + + // convert to string + s = num + STBSP__NUMSZ; + l = 0; + + for (;;) { + // do in 32-bit chunks (avoid lots of 64-bit divides even with constant denominators) + char *o = s - 8; + if (n64 >= 100000000) { + n = (stbsp__uint32)(n64 % 100000000); + n64 /= 100000000; + } else { + n = (stbsp__uint32)n64; + n64 = 0; + } + if ((fl & STBSP__TRIPLET_COMMA) == 0) { + do { + s -= 2; + *(stbsp__uint16 *)s = *(stbsp__uint16 *)&stbsp__digitpair.pair[(n % 100) * 2]; + n /= 100; + } while (n); + } + while (n) { + if ((fl & STBSP__TRIPLET_COMMA) && (l++ == 3)) { + l = 0; + *--s = stbsp__comma; + --o; + } else { + *--s = (char)(n % 10) + '0'; + n /= 10; + } + } + if (n64 == 0) { + if ((s[0] == '0') && (s != (num + STBSP__NUMSZ))) + ++s; + break; + } + while (s != o) + if ((fl & STBSP__TRIPLET_COMMA) && (l++ == 3)) { + l = 0; + *--s = stbsp__comma; + --o; + } else { + *--s = '0'; + } + } + + tail[0] = 0; + stbsp__lead_sign(fl, lead); + + // get the length that we copied + l = (stbsp__uint32)((num + STBSP__NUMSZ) - s); + if (l == 0) { + *--s = '0'; + l = 1; + } + cs = l + (3 << 24); + if (pr < 0) + pr = 0; + + scopy: + // get fw=leading/trailing space, pr=leading zeros + if (pr < (stbsp__int32)l) + pr = l; + n = pr + lead[0] + tail[0] + tz; + if (fw < (stbsp__int32)n) + fw = n; + fw -= n; + pr -= l; + + // handle right justify and leading zeros + if ((fl & STBSP__LEFTJUST) == 0) { + if (fl & STBSP__LEADINGZERO) // if leading zeros, everything is in pr + { + pr = (fw > pr) ? fw : pr; + fw = 0; + } else { + fl &= ~STBSP__TRIPLET_COMMA; // if no leading zeros, then no commas + } + } + + // copy the spaces and/or zeros + if (fw + pr) { + stbsp__int32 i; + stbsp__uint32 c; + + // copy leading spaces (or when doing %8.4d stuff) + if ((fl & STBSP__LEFTJUST) == 0) + while (fw > 0) { + stbsp__cb_buf_clamp(i, fw); + fw -= i; + while (i) { + if ((((stbsp__uintptr)bf) & 3) == 0) + break; + *bf++ = ' '; + --i; + } + while (i >= 4) { + *(stbsp__uint32 *)bf = 0x20202020; + bf += 4; + i -= 4; + } + while (i) { + *bf++ = ' '; + --i; + } + stbsp__chk_cb_buf(1); + } + + // copy leader + sn = lead + 1; + while (lead[0]) { + stbsp__cb_buf_clamp(i, lead[0]); + lead[0] -= (char)i; + while (i) { + *bf++ = *sn++; + --i; + } + stbsp__chk_cb_buf(1); + } + + // copy leading zeros + c = cs >> 24; + cs &= 0xffffff; + cs = (fl & STBSP__TRIPLET_COMMA) ? ((stbsp__uint32)(c - ((pr + cs) % (c + 1)))) : 0; + while (pr > 0) { + stbsp__cb_buf_clamp(i, pr); + pr -= i; + if ((fl & STBSP__TRIPLET_COMMA) == 0) { + while (i) { + if ((((stbsp__uintptr)bf) & 3) == 0) + break; + *bf++ = '0'; + --i; + } + while (i >= 4) { + *(stbsp__uint32 *)bf = 0x30303030; + bf += 4; + i -= 4; + } + } + while (i) { + if ((fl & STBSP__TRIPLET_COMMA) && (cs++ == c)) { + cs = 0; + *bf++ = stbsp__comma; + } else + *bf++ = '0'; + --i; + } + stbsp__chk_cb_buf(1); + } + } + + // copy leader if there is still one + sn = lead + 1; + while (lead[0]) { + stbsp__int32 i; + stbsp__cb_buf_clamp(i, lead[0]); + lead[0] -= (char)i; + while (i) { + *bf++ = *sn++; + --i; + } + stbsp__chk_cb_buf(1); + } + + // copy the string + n = l; + while (n) { + stbsp__int32 i; + stbsp__cb_buf_clamp(i, n); + n -= i; + STBSP__UNALIGNED(while (i >= 4) { + *(stbsp__uint32 volatile *)bf = *(stbsp__uint32 volatile *)s; + bf += 4; + s += 4; + i -= 4; + }) + while (i) { + *bf++ = *s++; + --i; + } + stbsp__chk_cb_buf(1); + } + + // copy trailing zeros + while (tz) { + stbsp__int32 i; + stbsp__cb_buf_clamp(i, tz); + tz -= i; + while (i) { + if ((((stbsp__uintptr)bf) & 3) == 0) + break; + *bf++ = '0'; + --i; + } + while (i >= 4) { + *(stbsp__uint32 *)bf = 0x30303030; + bf += 4; + i -= 4; + } + while (i) { + *bf++ = '0'; + --i; + } + stbsp__chk_cb_buf(1); + } + + // copy tail if there is one + sn = tail + 1; + while (tail[0]) { + stbsp__int32 i; + stbsp__cb_buf_clamp(i, tail[0]); + tail[0] -= (char)i; + while (i) { + *bf++ = *sn++; + --i; + } + stbsp__chk_cb_buf(1); + } + + // handle the left justify + if (fl & STBSP__LEFTJUST) + if (fw > 0) { + while (fw) { + stbsp__int32 i; + stbsp__cb_buf_clamp(i, fw); + fw -= i; + while (i) { + if ((((stbsp__uintptr)bf) & 3) == 0) + break; + *bf++ = ' '; + --i; + } + while (i >= 4) { + *(stbsp__uint32 *)bf = 0x20202020; + bf += 4; + i -= 4; + } + while (i--) + *bf++ = ' '; + stbsp__chk_cb_buf(1); + } + } + break; + + default: // unknown, just copy code + s = num + STBSP__NUMSZ - 1; + *s = f[0]; + l = 1; + fw = fl = 0; + lead[0] = 0; + tail[0] = 0; + pr = 0; + dp = 0; + cs = 0; + goto scopy; + } + ++f; + } +endfmt: + + if (!callback) + *bf = 0; + else + stbsp__flush_cb(); + +done: + return tlen + (int)(bf - buf); +} + +// cleanup +#undef STBSP__LEFTJUST +#undef STBSP__LEADINGPLUS +#undef STBSP__LEADINGSPACE +#undef STBSP__LEADING_0X +#undef STBSP__LEADINGZERO +#undef STBSP__INTMAX +#undef STBSP__TRIPLET_COMMA +#undef STBSP__NEGATIVE +#undef STBSP__METRIC_SUFFIX +#undef STBSP__NUMSZ +#undef stbsp__chk_cb_bufL +#undef stbsp__chk_cb_buf +#undef stbsp__flush_cb +#undef stbsp__cb_buf_clamp + +// ============================================================================ +// wrapper functions + +STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(sprintf)(char *buf, char const *fmt, ...) +{ + int result; + va_list va; + va_start(va, fmt); + result = STB_SPRINTF_DECORATE(vsprintfcb)(0, 0, buf, fmt, va); + va_end(va); + return result; +} + +typedef struct stbsp__context { + char *buf; + int count; + int length; + char tmp[STB_SPRINTF_MIN]; +} stbsp__context; + +static char *stbsp__clamp_callback(const char *buf, void *user, int len) +{ + stbsp__context *c = (stbsp__context *)user; + c->length += len; + + if (len > c->count) + len = c->count; + + if (len) { + if (buf != c->buf) { + const char *s, *se; + char *d; + d = c->buf; + s = buf; + se = buf + len; + do { + *d++ = *s++; + } while (s < se); + } + c->buf += len; + c->count -= len; + } + + if (c->count <= 0) + return c->tmp; + return (c->count >= STB_SPRINTF_MIN) ? c->buf : c->tmp; // go direct into buffer if you can +} + +static char * stbsp__count_clamp_callback( const char * buf, void * user, int len ) +{ + stbsp__context * c = (stbsp__context*)user; + (void) sizeof(buf); + + c->length += len; + return c->tmp; // go direct into buffer if you can +} + +STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsnprintf )( char * buf, int count, char const * fmt, va_list va ) +{ + stbsp__context c; + + if ( (count == 0) && !buf ) + { + c.length = 0; + + STB_SPRINTF_DECORATE( vsprintfcb )( stbsp__count_clamp_callback, &c, c.tmp, fmt, va ); + } + else + { + int l; + + c.buf = buf; + c.count = count; + c.length = 0; + + STB_SPRINTF_DECORATE( vsprintfcb )( stbsp__clamp_callback, &c, stbsp__clamp_callback(0,&c,0), fmt, va ); + + // zero-terminate + l = (int)( c.buf - buf ); + if ( l >= count ) // should never be greater, only equal (or less) than count + l = count - 1; + buf[l] = 0; + } + + return c.length; +} + +STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(snprintf)(char *buf, int count, char const *fmt, ...) +{ + int result; + va_list va; + va_start(va, fmt); + + result = STB_SPRINTF_DECORATE(vsnprintf)(buf, count, fmt, va); + va_end(va); + + return result; +} + +STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintf)(char *buf, char const *fmt, va_list va) +{ + return STB_SPRINTF_DECORATE(vsprintfcb)(0, 0, buf, fmt, va); +} + +// ======================================================================= +// low level float utility functions + +#ifndef STB_SPRINTF_NOFLOAT + +// copies d to bits w/ strict aliasing (this compiles to nothing on /Ox) +#define STBSP__COPYFP(dest, src) \ + { \ + int cn; \ + for (cn = 0; cn < 8; cn++) \ + ((char *)&dest)[cn] = ((char *)&src)[cn]; \ + } + +// get float info +static stbsp__int32 stbsp__real_to_parts(stbsp__int64 *bits, stbsp__int32 *expo, double value) +{ + double d; + stbsp__int64 b = 0; + + // load value and round at the frac_digits + d = value; + + STBSP__COPYFP(b, d); + + *bits = b & ((((stbsp__uint64)1) << 52) - 1); + *expo = (stbsp__int32)(((b >> 52) & 2047) - 1023); + + return (stbsp__int32)((stbsp__uint64) b >> 63); +} + +static double const stbsp__bot[23] = { + 1e+000, 1e+001, 1e+002, 1e+003, 1e+004, 1e+005, 1e+006, 1e+007, 1e+008, 1e+009, 1e+010, 1e+011, + 1e+012, 1e+013, 1e+014, 1e+015, 1e+016, 1e+017, 1e+018, 1e+019, 1e+020, 1e+021, 1e+022 +}; +static double const stbsp__negbot[22] = { + 1e-001, 1e-002, 1e-003, 1e-004, 1e-005, 1e-006, 1e-007, 1e-008, 1e-009, 1e-010, 1e-011, + 1e-012, 1e-013, 1e-014, 1e-015, 1e-016, 1e-017, 1e-018, 1e-019, 1e-020, 1e-021, 1e-022 +}; +static double const stbsp__negboterr[22] = { + -5.551115123125783e-018, -2.0816681711721684e-019, -2.0816681711721686e-020, -4.7921736023859299e-021, -8.1803053914031305e-022, 4.5251888174113741e-023, + 4.5251888174113739e-024, -2.0922560830128471e-025, -6.2281591457779853e-026, -3.6432197315497743e-027, 6.0503030718060191e-028, 2.0113352370744385e-029, + -3.0373745563400371e-030, 1.1806906454401013e-032, -7.7705399876661076e-032, 2.0902213275965398e-033, -7.1542424054621921e-034, -7.1542424054621926e-035, + 2.4754073164739869e-036, 5.4846728545790429e-037, 9.2462547772103625e-038, -4.8596774326570872e-039 +}; +static double const stbsp__top[13] = { + 1e+023, 1e+046, 1e+069, 1e+092, 1e+115, 1e+138, 1e+161, 1e+184, 1e+207, 1e+230, 1e+253, 1e+276, 1e+299 +}; +static double const stbsp__negtop[13] = { + 1e-023, 1e-046, 1e-069, 1e-092, 1e-115, 1e-138, 1e-161, 1e-184, 1e-207, 1e-230, 1e-253, 1e-276, 1e-299 +}; +static double const stbsp__toperr[13] = { + 8388608, + 6.8601809640529717e+028, + -7.253143638152921e+052, + -4.3377296974619174e+075, + -1.5559416129466825e+098, + -3.2841562489204913e+121, + -3.7745893248228135e+144, + -1.7356668416969134e+167, + -3.8893577551088374e+190, + -9.9566444326005119e+213, + 6.3641293062232429e+236, + -5.2069140800249813e+259, + -5.2504760255204387e+282 +}; +static double const stbsp__negtoperr[13] = { + 3.9565301985100693e-040, -2.299904345391321e-063, 3.6506201437945798e-086, 1.1875228833981544e-109, + -5.0644902316928607e-132, -6.7156837247865426e-155, -2.812077463003139e-178, -5.7778912386589953e-201, + 7.4997100559334532e-224, -4.6439668915134491e-247, -6.3691100762962136e-270, -9.436808465446358e-293, + 8.0970921678014997e-317 +}; + +#if defined(_MSC_VER) && (_MSC_VER <= 1200) +static stbsp__uint64 const stbsp__powten[20] = { + 1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, + 10000000000, + 100000000000, + 1000000000000, + 10000000000000, + 100000000000000, + 1000000000000000, + 10000000000000000, + 100000000000000000, + 1000000000000000000, + 10000000000000000000U +}; +#define stbsp__tento19th ((stbsp__uint64)1000000000000000000) +#else +static stbsp__uint64 const stbsp__powten[20] = { + 1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, + 10000000000ULL, + 100000000000ULL, + 1000000000000ULL, + 10000000000000ULL, + 100000000000000ULL, + 1000000000000000ULL, + 10000000000000000ULL, + 100000000000000000ULL, + 1000000000000000000ULL, + 10000000000000000000ULL +}; +#define stbsp__tento19th (1000000000000000000ULL) +#endif + +#define stbsp__ddmulthi(oh, ol, xh, yh) \ + { \ + double ahi = 0, alo, bhi = 0, blo; \ + stbsp__int64 bt; \ + oh = xh * yh; \ + STBSP__COPYFP(bt, xh); \ + bt &= ((~(stbsp__uint64)0) << 27); \ + STBSP__COPYFP(ahi, bt); \ + alo = xh - ahi; \ + STBSP__COPYFP(bt, yh); \ + bt &= ((~(stbsp__uint64)0) << 27); \ + STBSP__COPYFP(bhi, bt); \ + blo = yh - bhi; \ + ol = ((ahi * bhi - oh) + ahi * blo + alo * bhi) + alo * blo; \ + } + +#define stbsp__ddtoS64(ob, xh, xl) \ + { \ + double ahi = 0, alo, vh, t; \ + ob = (stbsp__int64)xh; \ + vh = (double)ob; \ + ahi = (xh - vh); \ + t = (ahi - xh); \ + alo = (xh - (ahi - t)) - (vh + t); \ + ob += (stbsp__int64)(ahi + alo + xl); \ + } + +#define stbsp__ddrenorm(oh, ol) \ + { \ + double s; \ + s = oh + ol; \ + ol = ol - (s - oh); \ + oh = s; \ + } + +#define stbsp__ddmultlo(oh, ol, xh, xl, yh, yl) ol = ol + (xh * yl + xl * yh); + +#define stbsp__ddmultlos(oh, ol, xh, yl) ol = ol + (xh * yl); + +static void stbsp__raise_to_power10(double *ohi, double *olo, double d, stbsp__int32 power) // power can be -323 to +350 +{ + double ph, pl; + if ((power >= 0) && (power <= 22)) { + stbsp__ddmulthi(ph, pl, d, stbsp__bot[power]); + } else { + stbsp__int32 e, et, eb; + double p2h, p2l; + + e = power; + if (power < 0) + e = -e; + et = (e * 0x2c9) >> 14; /* %23 */ + if (et > 13) + et = 13; + eb = e - (et * 23); + + ph = d; + pl = 0.0; + if (power < 0) { + if (eb) { + --eb; + stbsp__ddmulthi(ph, pl, d, stbsp__negbot[eb]); + stbsp__ddmultlos(ph, pl, d, stbsp__negboterr[eb]); + } + if (et) { + stbsp__ddrenorm(ph, pl); + --et; + stbsp__ddmulthi(p2h, p2l, ph, stbsp__negtop[et]); + stbsp__ddmultlo(p2h, p2l, ph, pl, stbsp__negtop[et], stbsp__negtoperr[et]); + ph = p2h; + pl = p2l; + } + } else { + if (eb) { + e = eb; + if (eb > 22) + eb = 22; + e -= eb; + stbsp__ddmulthi(ph, pl, d, stbsp__bot[eb]); + if (e) { + stbsp__ddrenorm(ph, pl); + stbsp__ddmulthi(p2h, p2l, ph, stbsp__bot[e]); + stbsp__ddmultlos(p2h, p2l, stbsp__bot[e], pl); + ph = p2h; + pl = p2l; + } + } + if (et) { + stbsp__ddrenorm(ph, pl); + --et; + stbsp__ddmulthi(p2h, p2l, ph, stbsp__top[et]); + stbsp__ddmultlo(p2h, p2l, ph, pl, stbsp__top[et], stbsp__toperr[et]); + ph = p2h; + pl = p2l; + } + } + } + stbsp__ddrenorm(ph, pl); + *ohi = ph; + *olo = pl; +} + +// given a float value, returns the significant bits in bits, and the position of the +// decimal point in decimal_pos. +/-INF and NAN are specified by special values +// returned in the decimal_pos parameter. +// frac_digits is absolute normally, but if you want from first significant digits (got %g and %e), or in 0x80000000 +static stbsp__int32 stbsp__real_to_str(char const **start, stbsp__uint32 *len, char *out, stbsp__int32 *decimal_pos, double value, stbsp__uint32 frac_digits) +{ + double d; + stbsp__int64 bits = 0; + stbsp__int32 expo, e, ng, tens; + + d = value; + STBSP__COPYFP(bits, d); + expo = (stbsp__int32)((bits >> 52) & 2047); + ng = (stbsp__int32)((stbsp__uint64) bits >> 63); + if (ng) + d = -d; + + if (expo == 2047) // is nan or inf? + { + *start = (bits & ((((stbsp__uint64)1) << 52) - 1)) ? "NaN" : "Inf"; + *decimal_pos = STBSP__SPECIAL; + *len = 3; + return ng; + } + + if (expo == 0) // is zero or denormal + { + if (((stbsp__uint64) bits << 1) == 0) // do zero + { + *decimal_pos = 1; + *start = out; + out[0] = '0'; + *len = 1; + return ng; + } + // find the right expo for denormals + { + stbsp__int64 v = ((stbsp__uint64)1) << 51; + while ((bits & v) == 0) { + --expo; + v >>= 1; + } + } + } + + // find the decimal exponent as well as the decimal bits of the value + { + double ph, pl; + + // log10 estimate - very specifically tweaked to hit or undershoot by no more than 1 of log10 of all expos 1..2046 + tens = expo - 1023; + tens = (tens < 0) ? ((tens * 617) / 2048) : (((tens * 1233) / 4096) + 1); + + // move the significant bits into position and stick them into an int + stbsp__raise_to_power10(&ph, &pl, d, 18 - tens); + + // get full as much precision from double-double as possible + stbsp__ddtoS64(bits, ph, pl); + + // check if we undershot + if (((stbsp__uint64)bits) >= stbsp__tento19th) + ++tens; + } + + // now do the rounding in integer land + frac_digits = (frac_digits & 0x80000000) ? ((frac_digits & 0x7ffffff) + 1) : (tens + frac_digits); + if ((frac_digits < 24)) { + stbsp__uint32 dg = 1; + if ((stbsp__uint64)bits >= stbsp__powten[9]) + dg = 10; + while ((stbsp__uint64)bits >= stbsp__powten[dg]) { + ++dg; + if (dg == 20) + goto noround; + } + if (frac_digits < dg) { + stbsp__uint64 r; + // add 0.5 at the right position and round + e = dg - frac_digits; + if ((stbsp__uint32)e >= 24) + goto noround; + r = stbsp__powten[e]; + bits = bits + (r / 2); + if ((stbsp__uint64)bits >= stbsp__powten[dg]) + ++tens; + bits /= r; + } + noround:; + } + + // kill long trailing runs of zeros + if (bits) { + stbsp__uint32 n; + for (;;) { + if (bits <= 0xffffffff) + break; + if (bits % 1000) + goto donez; + bits /= 1000; + } + n = (stbsp__uint32)bits; + while ((n % 1000) == 0) + n /= 1000; + bits = n; + donez:; + } + + // convert to string + out += 64; + e = 0; + for (;;) { + stbsp__uint32 n; + char *o = out - 8; + // do the conversion in chunks of U32s (avoid most 64-bit divides, worth it, constant denomiators be damned) + if (bits >= 100000000) { + n = (stbsp__uint32)(bits % 100000000); + bits /= 100000000; + } else { + n = (stbsp__uint32)bits; + bits = 0; + } + while (n) { + out -= 2; + *(stbsp__uint16 *)out = *(stbsp__uint16 *)&stbsp__digitpair.pair[(n % 100) * 2]; + n /= 100; + e += 2; + } + if (bits == 0) { + if ((e) && (out[0] == '0')) { + ++out; + --e; + } + break; + } + while (out != o) { + *--out = '0'; + ++e; + } + } + + *decimal_pos = tens; + *start = out; + *len = e; + return ng; +} + +#undef stbsp__ddmulthi +#undef stbsp__ddrenorm +#undef stbsp__ddmultlo +#undef stbsp__ddmultlos +#undef STBSP__SPECIAL +#undef STBSP__COPYFP + +#endif // STB_SPRINTF_NOFLOAT + +// clean up +#undef stbsp__uint16 +#undef stbsp__uint32 +#undef stbsp__int32 +#undef stbsp__uint64 +#undef stbsp__int64 +#undef STBSP__UNALIGNED + +#endif // STB_SPRINTF_IMPLEMENTATION + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ +DN_GCC_WARNING_POP +DN_MSVC_WARNING_POP + +DN_API void DN_BeginFrame (); + +#define DN_SPrintF(...) STB_SPRINTF_DECORATE(sprintf)(__VA_ARGS__) +#define DN_SNPrintF(...) STB_SPRINTF_DECORATE(snprintf)(__VA_ARGS__) +#define DN_VSPrintF(...) STB_SPRINTF_DECORATE(vsprintf)(__VA_ARGS__) +#define DN_VSNPrintF(...) STB_SPRINTF_DECORATE(vsnprintf)(__VA_ARGS__) + +DN_API bool DN_MemEq (void const *lhs, DN_USize lhs_size, void const *rhs, DN_USize rhs_size); + +DN_API DN_U64 DN_AtomicSetValue64 (DN_U64 volatile *target, DN_U64 value); +DN_API DN_U32 DN_AtomicSetValue32 (DN_U32 volatile *target, DN_U32 value); + +DN_API DN_CPUIDResult DN_CPUID (DN_CPUIDArgs args); +DN_API DN_USize DN_CPUHasFeatureArray (DN_CPUReport const *report, DN_CPUFeatureQuery *features, DN_USize features_size); +DN_API bool DN_CPUHasFeature (DN_CPUReport const *report, DN_CPUFeature feature); +DN_API bool DN_CPUHasAllFeatures (DN_CPUReport const *report, DN_CPUFeature const *features, DN_USize features_size); +DN_API void DN_CPUSetFeature (DN_CPUReport *report, DN_CPUFeature feature); +DN_API DN_CPUReport DN_CPUGetReport (); + +DN_API void DN_TicketMutex_Begin (DN_TicketMutex *mutex); +DN_API void DN_TicketMutex_End (DN_TicketMutex *mutex); +DN_API DN_UInt DN_TicketMutex_MakeTicket (DN_TicketMutex *mutex); +DN_API void DN_TicketMutex_BeginTicket (DN_TicketMutex const *mutex, DN_UInt ticket); +DN_API bool DN_TicketMutex_CanLock (DN_TicketMutex const *mutex, DN_UInt ticket); + +DN_API void DN_BitUnsetInplace (DN_USize *flags, DN_USize bitfield); +DN_API void DN_BitSetInplace (DN_USize *flags, DN_USize bitfield); +DN_API bool DN_BitIsSet (DN_USize bits, DN_USize bits_to_set); +DN_API bool DN_BitIsNotSet (DN_USize bits, DN_USize bits_to_check); +#define DN_BitClearNextLSB(value) (value) & ((value) - 1) + +DN_API DN_I64 DN_SafeAddI64 (DN_I64 a, DN_I64 b); +DN_API DN_I64 DN_SafeMulI64 (DN_I64 a, DN_I64 b); + +DN_API DN_U64 DN_SafeAddU64 (DN_U64 a, DN_U64 b); +DN_API DN_U64 DN_SafeMulU64 (DN_U64 a, DN_U64 b); + +DN_API DN_U64 DN_SafeSubU64 (DN_U64 a, DN_U64 b); +DN_API DN_U32 DN_SafeSubU32 (DN_U32 a, DN_U32 b); + +DN_API int DN_SaturateCastUSizeToInt (DN_USize val); +DN_API DN_I8 DN_SaturateCastUSizeToI8 (DN_USize val); +DN_API DN_I16 DN_SaturateCastUSizeToI16 (DN_USize val); +DN_API DN_I32 DN_SaturateCastUSizeToI32 (DN_USize val); +DN_API DN_I64 DN_SaturateCastUSizeToI64 (DN_USize val); + +DN_API int DN_SaturateCastU64ToInt (DN_U64 val); +DN_API DN_I8 DN_SaturateCastU8ToI8 (DN_U64 val); +DN_API DN_I16 DN_SaturateCastU16ToI16 (DN_U64 val); +DN_API DN_I32 DN_SaturateCastU32ToI32 (DN_U64 val); +DN_API DN_I64 DN_SaturateCastU64ToI64 (DN_U64 val); +DN_API DN_UInt DN_SaturateCastU64ToUInt (DN_U64 val); +DN_API DN_U8 DN_SaturateCastU64ToU8 (DN_U64 val); +DN_API DN_U16 DN_SaturateCastU64ToU16 (DN_U64 val); +DN_API DN_U32 DN_SaturateCastU64ToU32 (DN_U64 val); + +DN_API DN_U8 DN_SaturateCastUSizeToU8 (DN_USize val); +DN_API DN_U16 DN_SaturateCastUSizeToU16 (DN_USize val); +DN_API DN_U32 DN_SaturateCastUSizeToU32 (DN_USize val); +DN_API DN_U64 DN_SaturateCastUSizeToU64 (DN_USize val); + +DN_API int DN_SaturateCastISizeToInt (DN_ISize val); +DN_API DN_I8 DN_SaturateCastISizeToI8 (DN_ISize val); +DN_API DN_I16 DN_SaturateCastISizeToI16 (DN_ISize val); +DN_API DN_I32 DN_SaturateCastISizeToI32 (DN_ISize val); +DN_API DN_I64 DN_SaturateCastISizeToI64 (DN_ISize val); + +DN_API DN_UInt DN_SaturateCastISizeToUInt (DN_ISize val); +DN_API DN_U8 DN_SaturateCastISizeToU8 (DN_ISize val); +DN_API DN_U16 DN_SaturateCastISizeToU16 (DN_ISize val); +DN_API DN_U32 DN_SaturateCastISizeToU32 (DN_ISize val); +DN_API DN_U64 DN_SaturateCastISizeToU64 (DN_ISize val); + +DN_API DN_ISize DN_SaturateCastI64ToISize (DN_I64 val); +DN_API DN_I8 DN_SaturateCastI64ToI8 (DN_I64 val); +DN_API DN_I16 DN_SaturateCastI64ToI16 (DN_I64 val); +DN_API DN_I32 DN_SaturateCastI64ToI32 (DN_I64 val); + +DN_API DN_UInt DN_SaturateCastI64ToUInt (DN_I64 val); +DN_API DN_ISize DN_SaturateCastI64ToUSize (DN_I64 val); +DN_API DN_U8 DN_SaturateCastI64ToU8 (DN_I64 val); +DN_API DN_U16 DN_SaturateCastI64ToU16 (DN_I64 val); +DN_API DN_U32 DN_SaturateCastI64ToU32 (DN_I64 val); +DN_API DN_U64 DN_SaturateCastI64ToU64 (DN_I64 val); + +DN_API DN_I8 DN_SaturateCastIntToI8 (int val); +DN_API DN_I16 DN_SaturateCastIntToI16 (int val); +DN_API DN_U8 DN_SaturateCastIntToU8 (int val); +DN_API DN_U16 DN_SaturateCastIntToU16 (int val); +DN_API DN_U32 DN_SaturateCastIntToU32 (int val); +DN_API DN_U64 DN_SaturateCastIntToU64 (int val); + +DN_API void DN_ASanPoisonMemoryRegion (void const volatile *ptr, DN_USize size); +DN_API void DN_ASanUnpoisonMemoryRegion (void const volatile *ptr, DN_USize size); + +DN_API DN_F32 DN_EpsilonClampF32 (DN_F32 value, DN_F32 target, DN_F32 epsilon); + +DN_API DN_Arena DN_ArenaFromBuffer (void *buffer, DN_USize size, DN_ArenaFlags flags); +DN_API DN_Arena DN_ArenaFromMemFuncs (DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs); +DN_API void DN_ArenaDeinit (DN_Arena *arena); +DN_API bool DN_ArenaCommit (DN_Arena *arena, DN_U64 size); +DN_API bool DN_ArenaCommitTo (DN_Arena *arena, DN_U64 pos); +DN_API bool DN_ArenaGrow (DN_Arena *arena, DN_U64 reserve, DN_U64 commit); +DN_API void * DN_ArenaAlloc (DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZMem zmem); +DN_API void * DN_ArenaAllocContiguous (DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZMem zmem); +DN_API void * DN_ArenaCopy (DN_Arena *arena, void const *data, DN_U64 size, uint8_t align); +DN_API void DN_ArenaPopTo (DN_Arena *arena, DN_U64 init_used); +DN_API void DN_ArenaPop (DN_Arena *arena, DN_U64 amount); +DN_API DN_U64 DN_ArenaPos (DN_Arena const *arena); +DN_API void DN_ArenaClear (DN_Arena *arena); +DN_API bool DN_ArenaOwnsPtr (DN_Arena const *arena, void *ptr); +DN_API DN_Str8x64 DN_ArenaInfoStr8x64 (DN_ArenaInfo info); +DN_API DN_ArenaStats DN_ArenaSumStatsArray (DN_ArenaStats const *array, DN_USize size); +DN_API DN_ArenaStats DN_ArenaSumStats (DN_ArenaStats lhs, DN_ArenaStats rhs); +DN_API DN_ArenaStats DN_ArenaSumArenaArrayToStats(DN_Arena const *array, DN_USize size); +DN_API DN_ArenaTempMem DN_ArenaTempMemBegin (DN_Arena *arena); +DN_API void DN_ArenaTempMemEnd (DN_ArenaTempMem mem); +#define DN_ArenaNew(arena, T, zmem) (T *)DN_ArenaAlloc(arena, sizeof(T), alignof(T), zmem) +#define DN_ArenaNewZ(arena, T) (T *)DN_ArenaAlloc(arena, sizeof(T), alignof(T), DN_ZMem_Yes) + +#define DN_ArenaNewContiguous(arena, T, zmem) (T *)DN_ArenaAllocContiguous(arena, sizeof(T), alignof(T), zmem) +#define DN_ArenaNewContiguousZ(arena, T) (T *)DN_ArenaAllocContiguous(arena, sizeof(T), alignof(T), DN_ZMem_Yes) + +#define DN_ArenaNewArray(arena, T, count, zmem) (T *)DN_ArenaAlloc(arena, sizeof(T) * (count), alignof(T), zmem) +#define DN_ArenaNewArrayZ(arena, T, count) (T *)DN_ArenaAlloc(arena, sizeof(T) * (count), alignof(T), DN_ZMem_Yes) + +#define DN_ArenaNewCopy(arena, T, src) (T *)DN_ArenaCopy (arena, (src), sizeof(T), alignof(T)) +#define DN_ArenaNewArrayCopy(arena, T, src, count) (T *)DN_ArenaCopy (arena, (src), sizeof(T) * (count), alignof(T)) + +DN_API DN_Pool DN_PoolFromArena (DN_Arena *arena, DN_U8 align); +DN_API bool DN_PoolIsValid (DN_Pool const *pool); +DN_API void * DN_PoolAlloc (DN_Pool *pool, DN_USize size); +DN_API void DN_PoolDealloc (DN_Pool *pool, void *ptr); +DN_API void * DN_PoolCopy (DN_Pool *pool, void const *data, DN_U64 size, uint8_t align); +#define DN_PoolNew(pool, T) (T *)DN_PoolAlloc(pool, sizeof(T)) +#define DN_PoolNewArray(pool, T, count) (T *)DN_PoolAlloc(pool, count * sizeof(T)) +#define DN_PoolNewCopy(pool, T, src) (T *)DN_PoolCopy (pool, (src), sizeof(T), alignof(T)) +#define DN_PoolNewArrayCopy(pool, T, src, count) (T *)DN_PoolCopy (pool, (src), sizeof(T) * (count), alignof(T)) + +DN_API bool DN_CharIsAlphabet (char ch); +DN_API bool DN_CharIsDigit (char ch); +DN_API bool DN_CharIsAlphaNum (char ch); +DN_API bool DN_CharIsWhitespace (char ch); +DN_API bool DN_CharIsHex (char ch); +DN_API char DN_CharToLower (char ch); +DN_API char DN_CharToUpper (char ch); + +DN_API DN_U64FromResult DN_U64FromStr8 (DN_Str8 string, char separator); +DN_API DN_U64FromResult DN_U64FromPtr (void const *data, DN_USize size, char separator); +DN_API DN_U64 DN_U64FromPtrUnsafe (void const *data, DN_USize size, char separator); +DN_API DN_U64FromResult DN_U64FromHexPtr (void const *hex, DN_USize hex_count); +DN_API DN_U64 DN_U64FromHexPtrUnsafe (void const *hex, DN_USize hex_count); +DN_API DN_U64FromResult DN_U64FromHexStr8 (DN_Str8 hex); +DN_API DN_U64 DN_U64FromHexStr8Unsafe (DN_Str8 hex); +DN_API DN_I64FromResult DN_I64FromStr8 (DN_Str8 string, char separator); +DN_API DN_I64FromResult DN_I64FromPtr (void const *data, DN_USize size, char separator); +DN_API DN_I64 DN_I64FromPtrUnsafe (void const *data, DN_USize size, char separator); + +DN_API DN_USize DN_FmtVSize (DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API DN_USize DN_FmtSize (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_FmtAppendResult DN_FmtVAppend (char *buf, DN_USize *buf_size, DN_USize buf_max, char const *fmt, va_list args); +DN_API DN_FmtAppendResult DN_FmtAppend (char *buf, DN_USize *buf_size, DN_USize buf_max, char const *fmt, ...); +DN_API DN_FmtAppendResult DN_FmtAppendTruncate (char *buf, DN_USize *buf_size, DN_USize buf_max, DN_Str8 truncator, char const *fmt, ...); +DN_API DN_USize DN_CStr8Size (char const *src); +DN_API DN_USize DN_CStr16Size (wchar_t const *src); + +#define DN_Str16Lit(string) DN_Str16{(wchar_t *)(string), sizeof(string)/sizeof(string[0]) - 1} +#define DN_Str8Lit(c_str) DN_Literal(DN_Str8){(char *)(c_str), sizeof(c_str) - 1} +#define DN_Str8PrintFmt(string) (int)((string).size), (string).data +#define DN_Str8FromPtr(data, size) DN_Literal(DN_Str8){(char *)(data), (DN_USize)(size)} +#define DN_Str8FromStruct(ptr) DN_Str8FromPtr((ptr)->data, (ptr)->size) +DN_API DN_Str8 DN_Str8FromCStr8 (char const *src); +DN_API DN_Str8 DN_Str8FromArena (DN_Arena *arena, DN_USize size, DN_ZMem z_mem); +DN_API DN_Str8 DN_Str8FromPool (DN_Pool *pool, DN_USize size); +DN_API DN_Str8 DN_Str8FromPtrArena (DN_Arena *arena, void const *data, DN_USize size); +DN_API DN_Str8 DN_Str8FromPtrPool (DN_Pool *pool, void const *data, DN_USize size); +DN_API DN_Str8 DN_Str8FromStr8Arena (DN_Arena *arena, DN_Str8 string); +DN_API DN_Str8 DN_Str8FromStr8Pool (DN_Pool *pool, DN_Str8 string); +DN_API DN_Str8 DN_Str8FromFmtArena (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8 DN_Str8FromFmtVArena (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API DN_Str8 DN_Str8FromFmtPool (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8 DN_Str8FromByteCountType (DN_ByteCountType type); +DN_API DN_Str8x32 DN_Str8x32FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x32 DN_Str8x32FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API DN_Str8x64 DN_Str8x64FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x64 DN_Str8x64FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API DN_Str8x128 DN_Str8x128FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x256 DN_Str8x256FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API DN_Str8x256 DN_Str8x256FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x256 DN_Str8x256FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API DN_Str8x32 DN_Str8x32FromU64 (DN_U64 val, char separator); +DN_API bool DN_Str8IsAll (DN_Str8 string, DN_Str8IsAllType is_all); +DN_API char * DN_Str8End (DN_Str8 string); +DN_API DN_Str8 DN_Str8Slice (DN_Str8 string, DN_USize offset, DN_USize size); +DN_API DN_Str8 DN_Str8Advance (DN_Str8 string, DN_USize amount); +DN_API DN_Str8 DN_Str8NextLine (DN_Str8 string); +DN_API DN_Str8BSplitResult DN_Str8BSplitArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size); +DN_API DN_Str8BSplitResult DN_Str8BSplit (DN_Str8 string, DN_Str8 find); +DN_API DN_Str8BSplitResult DN_Str8BSplitLastArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size); +DN_API DN_Str8BSplitResult DN_Str8BSplitLast (DN_Str8 string, DN_Str8 find); +DN_API DN_USize DN_Str8Split (DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_USize splits_count, DN_Str8SplitIncludeEmptyStrings mode); +DN_API DN_Str8SplitResult DN_Str8SplitArena (DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode); +DN_API DN_Str8FindResult DN_Str8FindStr8Array (DN_Str8 string, DN_Str8 const *find, DN_USize find_size, DN_Str8EqCase eq_case); +DN_API DN_Str8FindResult DN_Str8FindStr8 (DN_Str8 string, DN_Str8 find, DN_Str8EqCase eq_case); +DN_API DN_Str8FindResult DN_Str8Find (DN_Str8 string, uint32_t flags); +DN_API DN_Str8 DN_Str8Segment (DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char); +DN_API DN_Str8 DN_Str8ReverseSegment (DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char); +DN_API bool DN_Str8Eq (DN_Str8 lhs, DN_Str8 rhs, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive); +DN_API bool DN_Str8EqInsensitive (DN_Str8 lhs, DN_Str8 rhs); +DN_API bool DN_Str8StartsWith (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive); +DN_API bool DN_Str8StartsWithInsensitive(DN_Str8 string, DN_Str8 prefix); +DN_API bool DN_Str8EndsWith (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive); +DN_API bool DN_Str8EndsWithInsensitive (DN_Str8 string, DN_Str8 prefix); +DN_API bool DN_Str8HasChar (DN_Str8 string, char ch); +DN_API DN_Str8 DN_Str8TrimPrefix (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive); +DN_API DN_Str8 DN_Str8TrimHexPrefix (DN_Str8 string); +DN_API DN_Str8 DN_Str8TrimSuffix (DN_Str8 string, DN_Str8 suffix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive); +DN_API DN_Str8 DN_Str8TrimAround (DN_Str8 string, DN_Str8 trim_string); +DN_API DN_Str8 DN_Str8TrimHeadWhitespace (DN_Str8 string); +DN_API DN_Str8 DN_Str8TrimTailWhitespace (DN_Str8 string); +DN_API DN_Str8 DN_Str8TrimWhitespaceAround (DN_Str8 string); +DN_API DN_Str8 DN_Str8TrimByteOrderMark (DN_Str8 string); +DN_API DN_Str8 DN_Str8FileNameFromPath (DN_Str8 path); +DN_API DN_Str8 DN_Str8FileNameNoExtension (DN_Str8 path); +DN_API DN_Str8 DN_Str8FilePathNoExtension (DN_Str8 path); +DN_API DN_Str8 DN_Str8FileExtension (DN_Str8 path); +DN_API DN_Str8 DN_Str8FileDirectoryFromPath(DN_Str8 path); +DN_API DN_Str8 DN_Str8AppendF (DN_Arena *arena, DN_Str8 string, char const *fmt, ...); +DN_API DN_Str8 DN_Str8AppendFV (DN_Arena *arena, DN_Str8 string, char const *fmt, va_list args); +DN_API DN_Str8 DN_Str8FillF (DN_Arena *arena, DN_USize count, char const *fmt, ...); +DN_API DN_Str8 DN_Str8FillFV (DN_Arena *arena, DN_USize count, char const *fmt, va_list args); +DN_API void DN_Str8Remove (DN_Str8 *string, DN_USize offset, DN_USize size); +DN_API DN_Str8TruncateResult DN_Str8TruncateMiddle (DN_Arena *arena, DN_Str8 str8, DN_U32 side_size, DN_Str8 truncator); +DN_API DN_Str8 DN_Str8Lower (DN_Arena *arena, DN_Str8 string); +DN_API DN_Str8 DN_Str8Upper (DN_Arena *arena, DN_Str8 string); + +DN_API DN_Str8Builder DN_Str8BuilderFromArena (DN_Arena *arena); +DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrRef (DN_Arena *arena, DN_Str8 const *strings, DN_USize size); +DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrCopy (DN_Arena *arena, DN_Str8 const *strings, DN_USize size); +DN_API DN_Str8Builder DN_Str8BuilderFromBuilder (DN_Arena *arena, DN_Str8Builder const *builder); +DN_API bool DN_Str8BuilderAddArrayRef (DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize size, DN_Str8BuilderAdd add); +DN_API bool DN_Str8BuilderAddArrayCopy (DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize size, DN_Str8BuilderAdd add); +DN_API bool DN_Str8BuilderAddFV (DN_Str8Builder *builder, DN_Str8BuilderAdd add, DN_FMT_ATTRIB char const *fmt, va_list args); +#define DN_Str8BuilderAppendArrayRef(builder, strings, size) DN_Str8BuilderAddArrayRef(builder, strings, size, DN_Str8BuilderAdd_Append) +#define DN_Str8BuilderAppendArrayCopy(builder, strings, size) DN_Str8BuilderAddArrayCopy(builder, strings, size, DN_Str8BuilderAdd_Append) +#define DN_Str8BuilderAppendSliceRef(builder, slice) DN_Str8BuilderAddArrayRef(builder, slice.data, slice.size, DN_Str8BuilderAdd_Append) +#define DN_Str8BuilderAppendSliceCopy(builder, slice) DN_Str8BuilderAddArrayCopy(builder, slice.data, slice.size, DN_Str8BuilderAdd_Append) +DN_API bool DN_Str8BuilderAppendRef (DN_Str8Builder *builder, DN_Str8 string); +DN_API bool DN_Str8BuilderAppendCopy (DN_Str8Builder *builder, DN_Str8 string); +#define DN_Str8BuilderAppendFV(builder, fmt, args) DN_Str8BuilderAddFV(builder, DN_Str8BuilderAdd_Append, fmt, args) +DN_API bool DN_Str8BuilderAppendF (DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...); +DN_API bool DN_Str8BuilderAppendBytesRef (DN_Str8Builder *builder, void const *ptr, DN_USize size); +DN_API bool DN_Str8BuilderAppendBytesCopy (DN_Str8Builder *builder, void const *ptr, DN_USize size); +DN_API bool DN_Str8BuilderAppendBuilderRef (DN_Str8Builder *dest, DN_Str8Builder const *src); +DN_API bool DN_Str8BuilderAppendBuilderCopy (DN_Str8Builder *dest, DN_Str8Builder const *src); +#define DN_Str8BuilderPrependArrayRef(builder, strings, size) DN_Str8BuilderAddArrayRef(builder, strings, size, DN_Str8BuilderAdd_Prepend) +#define DN_Str8BuilderPrependArrayCopy(builder, strings, size) DN_Str8BuilderAddArrayCopy(builder, strings, size, DN_Str8BuilderAdd_Prepend) +#define DN_Str8BuilderPrependSliceRef(builder, slice) DN_Str8BuilderAddArrayRef(builder, slice.data, slice.size, DN_Str8BuilderAdd_Prepend) +#define DN_Str8BuilderPrependSliceCopy(builder, slice) DN_Str8BuilderAddArrayCopy(builder, slice.data, slice.size, DN_Str8BuilderAdd_Prepend) +DN_API bool DN_Str8BuilderPrependRef (DN_Str8Builder *builder, DN_Str8 string); +DN_API bool DN_Str8BuilderPrependCopy (DN_Str8Builder *builder, DN_Str8 string); +#define DN_Str8BuilderPrependFV(builder, fmt, args) DN_Str8BuilderAddFV(builder, DN_Str8BuilderAdd_Prepend, fmt, args) +DN_API bool DN_Str8BuilderPrependF (DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...); +DN_API bool DN_Str8BuilderErase (DN_Str8Builder *builder, DN_Str8 string); +DN_API DN_Str8 DN_Str8BuilderBuild (DN_Str8Builder const *builder, DN_Arena *arena); +DN_API DN_Str8 DN_Str8BuilderBuildDelimited (DN_Str8Builder const *builder, DN_Str8 delimiter, DN_Arena *arena); +DN_API DN_Slice DN_Str8BuilderBuildSlice (DN_Str8Builder const *builder, DN_Arena *arena); + +DN_API int DN_EncodeUTF8Codepoint (uint8_t utf8[4], uint32_t codepoint); +DN_API int DN_EncodeUTF16Codepoint (uint16_t utf16[2], uint32_t codepoint); + +DN_API DN_U8 DN_U8FromHexNibble (char hex); +DN_API DN_NibbleFromU8Result DN_NibbleFromU8 (DN_U8 u8); + +DN_API DN_USize DN_BytesFromHexPtr (void const *hex, DN_USize hex_count, void *dest, DN_USize dest_count); +DN_API DN_Str8 DN_BytesFromHexPtrArena (void const *hex, DN_USize hex_count, DN_Arena *arena); +DN_API DN_USize DN_BytesFromHexStr8 (DN_Str8 hex, void *dest, DN_USize dest_count); +DN_API DN_Str8 DN_BytesFromHexStr8Arena (DN_Str8 hex, DN_Arena *arena); +DN_API DN_U8x16 DN_BytesFromHex32Ptr (void const *hex, DN_USize hex_count); +DN_API DN_U8x32 DN_BytesFromHex64Ptr (void const *hex, DN_USize hex_count); + +DN_API DN_HexU64Str8 DN_HexFromU64 (DN_U64 value, DN_HexFromU64Type type); +DN_API DN_USize DN_HexFromBytesPtr (void const *bytes, DN_USize bytes_count, void *hex, DN_USize hex_count); +DN_API DN_Str8 DN_HexFromBytesPtrArena (void const *bytes, DN_USize bytes_count, DN_Arena *arena); +DN_API DN_Hex32 DN_HexFromBytes16Ptr (void const *bytes, DN_USize bytes_count); +DN_API DN_Hex64 DN_HexFromBytes32Ptr (void const *bytes, DN_USize bytes_count); +DN_API DN_Hex128 DN_HexFromBytes64Ptr (void const *bytes, DN_USize bytes_count); + +DN_API DN_Str8x128 DN_AgeStr8FromMsU64 (DN_U64 duration_ms, DN_AgeUnit units); +DN_API DN_Str8x128 DN_AgeStr8FromSecU64 (DN_U64 duration_ms, DN_AgeUnit units); +DN_API DN_Str8x128 DN_AgeStr8FromSecF64 (DN_F64 sec, DN_AgeUnit units); + +DN_API DN_ByteCountResult DN_ByteCountFromType (DN_U64 bytes, DN_ByteCountType type); +#define DN_ByteCount(bytes) DN_ByteCountFromType(bytes, DN_ByteCountType_Auto) +DN_API DN_Str8x32 DN_ByteCountStr8x32FromType (DN_U64 bytes, DN_ByteCountType type); +#define DN_ByteCountStr8x32(bytes) DN_ByteCountStr8x32FromType(bytes, DN_ByteCountType_Auto) + +#define DN_ProfilerZoneLoop(prof, name, index) \ + DN_ProfilerZone DN_UniqueName(zone_) = DN_ProfilerBeginZone(prof, DN_Str8Lit(name), index), DN_UniqueName(dummy_) = {}; \ + DN_UniqueName(dummy_).begin_tsc == 0; \ + DN_ProfilerEndZone(prof, DN_UniqueName(zone_)), DN_UniqueName(dummy_).begin_tsc = 1 + +#define DN_ProfilerZoneLoopAuto(prof, name) DN_ProfilerZoneLoop(prof, name, __COUNTER__ + 1) +DN_API DN_Profiler DN_ProfilerInit (DN_ProfilerAnchor *anchors, DN_USize count, DN_USize anchors_per_frame, DN_ProfilerTSCNowFunc *tsc_now, DN_U64 tsc_frequency); +DN_API DN_ProfilerZone DN_ProfilerBeginZone (DN_Profiler *profiler, DN_Str8 name, DN_U16 anchor_index); +#define DN_ProfilerBeginZoneAuto(prof, name) DN_ProfilerBeginZone(prof, DN_Str8Lit(name), __COUNTER__ + 1) +DN_API void DN_ProfilerEndZone (DN_Profiler *profiler, DN_ProfilerZone zone); +DN_API DN_USize DN_ProfilerFrameCount (DN_Profiler const *profiler); +DN_API DN_ProfilerAnchorArray DN_ProfilerFrameAnchorsFromIndex (DN_Profiler *profiler, DN_USize frame_index); +DN_API DN_ProfilerAnchorArray DN_ProfilerFrameAnchors (DN_Profiler *profiler); +DN_API void DN_ProfilerNewFrame (DN_Profiler *profiler); +DN_API void DN_ProfilerDump (DN_Profiler *profiler); +DN_API DN_F64 DN_ProfilerSecFromTSC (DN_Profiler *profiler, DN_U64 duration_tsc); +DN_API DN_F64 DN_ProfilerMsFromTSC (DN_Profiler *profiler, DN_U64 duration_tsc); + +#endif // !defined(DN_BASE_H) +// DN: Single header generator commented out this header => #include "Base/dn_base_os.h" +#if !defined(DN_BASE_OS_H) +#define DN_BASE_OS_H + +// DN: Single header generator commented out this header => #include "../dn_base_inc.h" + +// NOTE: OS primitives that the OS layer can provide for the base layer but is optional. + +struct DN_StackTraceFrame +{ + DN_U64 address; + DN_U64 line_number; + DN_Str8 file_name; + DN_Str8 function_name; +}; + +struct DN_StackTraceRawFrame +{ + void *process; + DN_U64 base_addr; +}; + +struct DN_StackTraceWalkResult +{ + void *process; // [Internal] Windows handle to the process + DN_U64 *base_addr; // The addresses of the functions in the stack trace + DN_U16 size; // The number of `base_addr`'s stored from the walk +}; + +struct DN_StackTraceWalkResultIterator +{ + DN_StackTraceRawFrame raw_frame; + DN_U16 index; +}; + + +#if defined(DN_FREESTANDING) +#define DN_StackTraceWalkStr8FromHeap(...) DN_Str8Lit("N/A") +#define DN_StackTraceWalk(...) +#define DN_StackTraceWalkResultIterate(...) +#define DN_StackTraceWalkResultToStr8(...) DN_Str8Lit("N/A") +#define DN_StackTraceWalkStr8(...) DN_Str8Lit("N/A") +#define DN_StackTraceWalkStr8FromHeap(...) DN_Str8Lit("N/A") +#define DN_StackTraceGetFrames(...) +#define DN_StackTraceRawFrameToFrame(...) +#define DN_StackTracePrint(...) +#define DN_StackTraceReloadSymbols(...) +#else +DN_API DN_StackTraceWalkResult DN_StackTraceWalk (struct DN_Arena *arena, DN_U16 limit); +DN_API bool DN_StackTraceWalkResultIterate(DN_StackTraceWalkResultIterator *it, DN_StackTraceWalkResult const *walk); +DN_API DN_Str8 DN_StackTraceWalkResultToStr8 (struct DN_Arena *arena, DN_StackTraceWalkResult const *walk, DN_U16 skip); +DN_API DN_Str8 DN_StackTraceWalkStr8 (struct DN_Arena *arena, DN_U16 limit, DN_U16 skip); +DN_API DN_Str8 DN_StackTraceWalkStr8FromHeap (DN_U16 limit, DN_U16 skip); +DN_API DN_Slice DN_StackTraceGetFrames (struct DN_Arena *arena, DN_U16 limit); +DN_API DN_StackTraceFrame DN_StackTraceRawFrameToFrame (struct DN_Arena *arena, DN_StackTraceRawFrame raw_frame); +DN_API void DN_StackTracePrint (DN_U16 limit); +DN_API void DN_StackTraceReloadSymbols (); +#endif +#endif // !defined(DN_BASE_OS_H) +// DN: Single header generator commented out this header => #include "Base/dn_base_assert.h" +#if !defined(DN_BASE_ASSERT_H) +#define DN_BASE_ASSERT_H + +#define DN_HardAssertF(expr, fmt, ...) \ + do { \ + if (!(expr)) { \ + DN_Str8 stack_trace_ = DN_StackTraceWalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \ + DN_LOG_ErrorF("Hard assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ + DN_Str8PrintFmt(stack_trace_), \ + ##__VA_ARGS__); \ + DN_DebugBreak; \ + } \ + } while (0) +#define DN_HardAssert(expr) DN_HardAssertF(expr, "") + +// NOTE: Our default assert requires stack traces which has a bit of a chicken-and-egg problem if +// we're trying to detect some code related to the DN startup sequence. If we try to assert before +// the OS layer is initialised stack-traces will try to use temporary memory which requires TLS to +// be setup which belongs to the OS. +// +// This causes recursion errors as they call into each other. We use RawAsserts for these kind of +// checks. +#if defined(DN_NO_ASSERT) + #define DN_RawAssert(...) + #define DN_Assert(...) + #define DN_AssertOnce(...) + #define DN_AssertF(...) + #define DN_AssertFOnce(...) +#else + #define DN_RawAssert(expr) do { if (!(expr)) DN_DebugBreak; } while (0) + + #define DN_AssertF(expr, fmt, ...) \ + do { \ + if (!(expr)) { \ + DN_Str8 stack_trace_ = DN_StackTraceWalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \ + DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ + DN_Str8PrintFmt(stack_trace_), \ + ##__VA_ARGS__); \ + DN_DebugBreak; \ + } \ + } while (0) + + #define DN_AssertFOnce(expr, fmt, ...) \ + do { \ + static bool once = true; \ + if (!(expr) && once) { \ + once = false; \ + DN_Str8 stack_trace_ = DN_StackTraceWalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \ + DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ + DN_Str8PrintFmt(stack_trace_), \ + ##__VA_ARGS__); \ + DN_DebugBreak; \ + } \ + } while (0) + + #define DN_Assert(expr) DN_AssertF((expr), "") + #define DN_AssertOnce(expr) DN_AssertFOnce((expr), "") +#endif + +#define DN_InvalidCodePathF(fmt, ...) DN_HardAssertF(0, fmt, ##__VA_ARGS__) +#define DN_InvalidCodePath DN_InvalidCodePathF("Invalid code path triggered") +#define DN_StaticAssert(expr) \ + DN_GCC_WARNING_PUSH \ + DN_GCC_WARNING_DISABLE(-Wunused-local-typedefs) \ + typedef char DN_TokenCombine(static_assert_dummy__, __LINE__)[(expr) ? 1 : -1]; \ + DN_GCC_WARNING_POP + +#define DN_Check(expr) DN_CheckF(expr, "") +#if defined(DN_NO_CHECK_BREAK) + #define DN_CheckF(expr, fmt, ...) \ + ((expr) ? true : (DN_LOG_WarningF(fmt, ##__VA_ARGS__), false)) +#else + #define DN_CheckF(expr, fmt, ...) \ + ((expr) ? true : (DN_LOG_ErrorF(fmt, ##__VA_ARGS__), DN_StackTracePrint(128 /*limit*/), DN_DebugBreak, false)) +#endif + +#endif +// DN: Single header generator commented out this header => #include "Base/dn_base_log.h" +#if !defined(DN_BASE_LOG_H) +#define DN_BASE_LOG_H + +// DN: Single header generator commented out this header => #include "../dn_base_inc.h" + +enum DN_LOGType +{ + DN_LOGType_Debug, + DN_LOGType_Info, + DN_LOGType_Warning, + DN_LOGType_Error, + DN_LOGType_Count, +}; + +enum DN_LOGBold +{ + DN_LOGBold_No, + DN_LOGBold_Yes, +}; + +struct DN_LOGStyle +{ + DN_LOGBold bold; + bool colour; + DN_U8 r, g, b; +}; + +struct DN_LOGTypeParam +{ + bool is_u32_enum; + DN_U32 u32; + DN_Str8 str8; +}; + +enum DN_LOGColourType +{ + DN_LOGColourType_Fg, + DN_LOGColourType_Bg, +}; + +struct DN_LOGDate +{ + DN_U16 year; + DN_U8 month; + DN_U8 day; + + DN_U8 hour; + DN_U8 minute; + DN_U8 second; +}; + +struct DN_LOGPrefixSize +{ + DN_USize size; + DN_USize padding; +}; + +typedef void DN_LOGEmitFromTypeFVFunc(DN_LOGTypeParam type, void *user_data, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, va_list args); + +#define DN_LOG_ResetEscapeCode "\x1b[0m" +#define DN_LOG_BoldEscapeCode "\x1b[1m" +DN_API DN_Str8 DN_LOG_ColourEscapeCodeStr8FromRGB(DN_LOGColourType colour, DN_U8 r, DN_U8 g, DN_U8 b); +DN_API DN_Str8 DN_LOG_ColourEscapeCodeStr8FromU32(DN_LOGColourType colour, DN_U32 value); +DN_API DN_LOGPrefixSize DN_LOG_MakePrefix (DN_LOGStyle style, DN_LOGTypeParam type, DN_CallSite call_site, DN_LOGDate date, char *dest, DN_USize dest_size); +DN_API void DN_LOG_SetEmitFromTypeFVFunc (DN_LOGEmitFromTypeFVFunc *print_func, void *user_data); +DN_API void DN_LOG_EmitFromType (DN_LOGTypeParam type, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_LOGTypeParam DN_LOG_MakeU32LogTypeParam (DN_LOGType type); +#define DN_LOG_DebugF(fmt, ...) DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Debug), DN_CALL_SITE, fmt, ##__VA_ARGS__) +#define DN_LOG_InfoF(fmt, ...) DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Info), DN_CALL_SITE, fmt, ##__VA_ARGS__) +#define DN_LOG_WarningF(fmt, ...) DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Warning), DN_CALL_SITE, fmt, ##__VA_ARGS__) +#define DN_LOG_ErrorF(fmt, ...) DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Error), DN_CALL_SITE, fmt, ##__VA_ARGS__) +#endif // !defined(DN_BASE_LOG_H) +// DN: Single header generator commented out this header => #include "Base/dn_base_containers.h" +#if !defined(DN_CONTAINERS_H) +#define DN_CONTAINERS_H + +// DN: Single header generator commented out this header => #include "../dn_base_inc.h" + +struct DN_Ring +{ + DN_U64 size; + char *base; + DN_U64 write_pos; + DN_U64 read_pos; +}; + +// NOTE: DN_CArray ///////////////////////////////////////////////////////////////////////////////// +enum DN_ArrayErase +{ + DN_ArrayErase_Unstable, + DN_ArrayErase_Stable, +}; + +enum DN_ArrayAdd +{ + DN_ArrayAdd_Append, + DN_ArrayAdd_Prepend, +}; + +struct DN_ArrayEraseResult +{ + // The next index your for-index should be set to such that you can continue + // to iterate the remainder of the array, e.g: + // + // for (DN_USize index = 0; index < array.size; index++) { + // if (erase) + // index = DN_FArray_EraseRange(&array, index, -3, DN_ArrayErase_Unstable); + // } + DN_USize it_index; + DN_USize items_erased; // The number of items erased +}; + +template struct DN_ArrayFindResult +{ + T *data; // Pointer to the value if a match is found, null pointer otherwise + DN_USize index; // Index to the value if a match is found, 0 otherwise +}; + +#if !defined(DN_NO_SARRAY) +// NOTE: DN_SArray ///////////////////////////////////////////////////////////////////////////////// +template struct DN_SArray +{ + T *data; // Pointer to the start of the array items in the block of memory + DN_USize size; // Number of items currently in the array + DN_USize max; // Maximum number of items this array can store + + T *begin() { return data; } + T *end () { return data + size; } + T const *begin() const { return data; } + T const *end () const { return data + size; } +}; +#endif // !defined(DN_NO_SARRAY) + +#if !defined(DN_NO_FARRAY) +// NOTE: DN_FArray ///////////////////////////////////////////////////////////////////////////////// +template struct DN_FArray +{ + T data[N]; // Pointer to the start of the array items in the block of memory + DN_USize size; // Number of items currently in the array + + T *begin() { return data; } + T *end () { return data + size; } + T const *begin() const { return data; } + T const *end () const { return data + size; } +}; + +template using DN_FArray8 = DN_FArray; +template using DN_FArray16 = DN_FArray; +template using DN_FArray32 = DN_FArray; +template using DN_FArray64 = DN_FArray; +#endif // !defined(DN_NO_FARRAY) + +#if !defined(DN_NO_DSMAP) +// NOTE: DN_DSMap ////////////////////////////////////////////////////////////////////////////////// +enum DN_DSMapKeyType +{ + // Key | Key Hash | Map Index + DN_DSMapKeyType_Invalid, + DN_DSMapKeyType_U64, // U64 | Hash(U64) | Hash(U64) % map_size + DN_DSMapKeyType_U64NoHash, // U64 | U64 | U64 % map_size + DN_DSMapKeyType_Buffer, // Buffer | Hash(buffer) | Hash(buffer) % map_size + DN_DSMapKeyType_BufferAsU64NoHash, // Buffer | U64(buffer[0:4]) | U64(buffer[0:4]) % map_size +}; + +struct DN_DSMapKey +{ + DN_DSMapKeyType type; + DN_U32 hash; // Hash to lookup in the map. If it equals, we check that the original key payload matches + void const *buffer_data; + DN_U32 buffer_size; + DN_U64 u64; + bool no_copy_buffer; +}; + +template +struct DN_DSMapSlot +{ + DN_DSMapKey key; // Hash table lookup key + T value; // Hash table value +}; + +typedef DN_U32 DN_DSMapFlags; +enum DN_DSMapFlags_ +{ + DN_DSMapFlags_Nil = 0, + DN_DSMapFlags_DontFreeArenaOnResize = 1 << 0, +}; + +using DN_DSMapHashFunction = DN_U32(DN_DSMapKey key, DN_U32 seed); +template struct DN_DSMap +{ + DN_U32 *hash_to_slot; // Mapping from hash to a index in the slots array + DN_DSMapSlot *slots; // Values of the array stored contiguously, non-sorted order + DN_U32 size; // Total capacity of the map and is a power of two + DN_U32 occupied; // Number of slots used in the hash table + DN_Arena *arena; // Backing arena for the hash table + DN_Pool pool; // Allocator for keys that are variable-sized buffers + DN_U32 initial_size; // Initial map size, map cannot shrink on erase below this size + DN_DSMapHashFunction *hash_function; // Custom hashing function to use if field is set + DN_U32 hash_seed; // Seed for the hashing function, when 0, DN_DS_MAP_DEFAULT_HASH_SEED is used + DN_DSMapFlags flags; +}; + +template struct DN_DSMapResult +{ + bool found; + DN_DSMapSlot *slot; + T *value; +}; +#endif // !defined(DN_NO_DSMAP) + +#if !defined(DN_NO_LIST) +// NOTE: DN_List /////////////////////////////////////////////////////////////////////////////////// +template struct DN_ListChunk +{ + T *data; + DN_USize size; + DN_USize count; + DN_ListChunk *next; + DN_ListChunk *prev; +}; + +template struct DN_ListIterator +{ + DN_B32 init; // True if DN_List_Iterate has been called at-least once on this iterator + DN_ListChunk *chunk; // The chunk that the iterator is reading from + DN_USize chunk_data_index; // The index in the chunk the iterator is referencing + DN_USize index; // The index of the item in the list as if it was flat array + T *data; // Pointer to the data the iterator is referencing. Nullptr if invalid. +}; + +template struct DN_List +{ + DN_USize count; // Cumulative count of all items made across all list chunks + DN_USize chunk_size; // When new ListChunk's are required, the minimum 'data' entries to allocate for that node. + DN_ListChunk *head; + DN_ListChunk *tail; +}; +#endif // !defined(DN_NO_LIST) + +// NOTE: Macros for operating on data structures that are embedded into a C style struct or from a +// set of defined variables from the available scope. Keep it stupid simple, structs and functions. +// Minimal amount of container types with flexible construction leads to less duplicated container +// code and less template meta-programming. +// +// LArray => Literal Array +// Define a C array and size: +// +// ``` +// MyStruct buffer[TB_ASType_Count] = {}; +// DN_USize size = 0; +// MyStruct *item = DN_LArray_Make(buffer, size, DN_ArrayCountU(buffer), DN_ZMem_No); +// ``` +// +// IArray => Intrusive Array +// Define a struct with the members 'data', 'size' and 'max': +// +// ``` +// struct MyArray { +// MyStruct *data; +// DN_USize size; +// DN_USize max; +// } my_array = {}; +// +// MyStruct *item = DN_IArray_Make(&my_array, MyArray, DN_ZMem_No); +// ``` +// ISLList => Intrusive Singly Linked List +// Define a struct with the members 'next': +// +// ``` +// struct MyLinkItem { +// int data; +// MyLinkItem *next; +// } my_link = {}; +// +// MyLinkItem *first_item = DN_ISLList_Detach(&my_link, MyLinkItem); +// ``` + +#define DN_DLList_Init(list) \ + (list)->next = (list)->prev = (list) + +#define DN_DLList_IsSentinel(list, item) ((list) == (item)) + +#define DN_DLList_InitArena(list, T, arena) \ + do { \ + (list) = DN_ArenaNew(arena, T, DN_ZMem_Yes); \ + DN_DLList_Init(list); \ + } while (0) + +#define DN_DLList_InitPool(list, T, pool) \ + do { \ + (list) = DN_PoolNew(pool, T); \ + DN_DLList_Init(list); \ + } while (0) + +#define DN_DLList_Detach(item) \ + do { \ + if (item) { \ + (item)->prev->next = (item)->next; \ + (item)->next->prev = (item)->prev; \ + (item)->next = nullptr; \ + (item)->prev = nullptr; \ + } \ + } while (0) + +#define DN_DLList_Dequeue(list, dest_ptr) \ + if (DN_DLList_HasItems(list)) { \ + dest_ptr = (list)->next; \ + DN_DLList_Detach(dest_ptr); \ + } + +#define DN_DLList_Append(list, item) \ + do { \ + if (item) { \ + if ((item)->next) \ + DN_DLList_Detach(item); \ + (item)->next = (list)->next; \ + (item)->prev = (list); \ + (item)->next->prev = (item); \ + (item)->prev->next = (item); \ + } \ + } while (0) + +#define DN_DLList_Prepend(list, item) \ + do { \ + if (item) { \ + if ((item)->next) \ + DN_DLList_Detach(item); \ + (item)->next = (list); \ + (item)->prev = (list)->prev; \ + (item)->next->prev = (item); \ + (item)->prev->next = (item); \ + } \ + } while (0) + +#define DN_DLList_IsEmpty(list) \ + (!(list) || ((list) == (list)->next)) + +#define DN_DLList_IsInit(list) \ + ((list)->next && (list)->prev) + +#define DN_DLList_HasItems(list) \ + ((list) && ((list) != (list)->next)) + +#define DN_DLList_ForEach(it, list) \ + auto *it = (list)->next; (it) != (list); (it) = (it)->next + +#define DN_DoublyLLDetach(head, ptr) \ + do { \ + if ((head) && (head) == (ptr)) \ + (head) = (head)->next; \ + if ((ptr)) { \ + if ((ptr)->next) \ + (ptr)->next->prev = (ptr)->prev; \ + if ((ptr)->prev) \ + (ptr)->prev->next = (ptr)->next; \ + (ptr)->prev = (ptr)->next = 0; \ + } \ + } while (0) + +#define DN_DoublyLLAppend(head, ptr) \ + do { \ + if ((ptr)) { \ + DN_AssertF((ptr)->prev == 0 && (ptr)->next == 0, "Detach the pointer first"); \ + (ptr)->prev = (head); \ + (ptr)->next = 0; \ + if ((head)) { \ + (ptr)->next = (head)->next; \ + (head)->next = (ptr); \ + } else { \ + (head) = (ptr); \ + } \ + } \ + } while (0) + +#define DN_DoublyLLPrepend(head, ptr) \ + do { \ + if ((ptr)) { \ + DN_AssertF((ptr)->prev == 0 && (ptr)->next == 0, "Detach the pointer first"); \ + (ptr)->prev = nullptr; \ + (ptr)->next = (head); \ + if ((head)) { \ + (ptr)->prev = (head)->prev; \ + (head)->prev = (ptr); \ + } else { \ + (head) = (ptr); \ + } \ + } \ + } while (0) + +#define DN_ISLList_Detach(list) (decltype(list))DN_CSLList_Detach((void **)&(list), (void **)&(list)->next) + +#define DN_LArray_ResizeFromPool(c_array, size, max, pool, new_max) DN_CArray2_ResizeFromPool((void **)&(c_array), size, max, sizeof((c_array)[0]), pool, new_max) +#define DN_LArray_GrowFromPool(c_array, size, max, pool, new_max) DN_CArray2_GrowFromPool((void **)&(c_array), size, max, sizeof((c_array)[0]), pool, new_max) +#define DN_LArray_GrowIfNeededFromPool(c_array, size, max, pool, add_count) DN_CArray2_GrowIfNeededFromPool((void **)(c_array), size, max, sizeof((c_array)[0]), pool, add_count) +#define DN_LArray_MakeArray(c_array, size, max, count, z_mem) (decltype(&(c_array)[0]))DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), count, z_mem) +#define DN_LArray_MakeArrayZ(c_array, size, max, count) (decltype(&(c_array)[0]))DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), count, DN_ZMem_Yes) +#define DN_LArray_Make(c_array, size, max, z_mem) (decltype(&(c_array)[0]))DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), 1, z_mem) +#define DN_LArray_MakeZ(c_array, size, max) (decltype(&(c_array)[0]))DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), 1, DN_ZMem_Yes) +#define DN_LArray_AddArray(c_array, size, max, items, count, add) (decltype(&(c_array)[0]))DN_CArray2_AddArray(c_array, size, max, sizeof((c_array)[0]), items, count, add) +#define DN_LArray_Add(c_array, size, max, item, add) (decltype(&(c_array)[0]))DN_CArray2_AddArray(c_array, size, max, sizeof((c_array)[0]), &item, 1, add) +#define DN_LArray_AppendArray(c_array, size, max, items, count) (decltype(&(c_array)[0]))DN_CArray2_AddArray(c_array, size, max, sizeof((c_array)[0]), items, count, DN_ArrayAdd_Append) +#define DN_LArray_Append(c_array, size, max, item) (decltype(&(c_array)[0]))DN_CArray2_AddArray(c_array, size, max, sizeof((c_array)[0]), &item, 1, DN_ArrayAdd_Append) +#define DN_LArray_PrependArray(c_array, size, max, items, count) (decltype(&(c_array)[0]))DN_CArray2_AddArray(c_array, size, max, sizeof((c_array)[0]), items, count, DN_ArrayAdd_Prepend) +#define DN_LArray_Prepend(c_array, size, max, item) (decltype(&(c_array)[0]))DN_CArray2_AddArray(c_array, size, max, sizeof((c_array)[0]), &item, 1, DN_ArrayAdd_Prepend) +#define DN_LArray_EraseRange(c_array, size, begin_index, count, erase) DN_CArray2_EraseRange(c_array, size, sizeof((c_array)[0]), begin_index, count, erase) +#define DN_LArray_Erase(c_array, size, index, erase) DN_CArray2_EraseRange(c_array, size, sizeof((c_array)[0]), index, 1, erase) +#define DN_LArray_InsertArray(c_array, size, max, index, items, count) (decltype(&(c_array)[0]))DN_CArray2_InsertArray(c_array, size, max, sizeof((c_array)[0]), index, items, count) +#define DN_LArray_Insert(c_array, size, max, index, item) (decltype(&(c_array)[0]))DN_CArray2_InsertArray(c_array, size, max, sizeof((c_array)[0]), index, &item, 1) + +#define DN_IArray_ResizeFromPool(array, pool, new_max) DN_CArray2_ResizeFromPool((void **)(&(array)->data), &(array)->size, &(array)->max, sizeof((array)->data[0]), pool, new_max) +#define DN_IArray_GrowFromPool(array, pool, new_max) DN_CArray2_GrowFromPool((void **)(&(array)->data), &(array)->size, &(array)->max, sizeof((array)->data[0]), pool, new_max) +#define DN_IArray_GrowIfNeededFromPool(array, pool, add_count) DN_CArray2_GrowIfNeededFromPool((void **)(&(array)->data), (array)->size, &(array)->max, sizeof((array)->data[0]), pool, add_count) +#define DN_IArray_MakeArray(array, count, z_mem) (decltype(&((array)->data)[0]))DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), count, z_mem) +#define DN_IArray_MakeArrayZ(array, count) (decltype(&((array)->data)[0]))DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), count, DN_ZMem_Yes) +#define DN_IArray_Make(array, z_mem) (decltype(&((array)->data)[0]))DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), 1, z_mem) +#define DN_IArray_MakeZ(array) (decltype(&((array)->data)[0]))DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), 1, DN_ZMem_Yes) +#define DN_IArray_AddArray(array, items, count, add) (decltype(&((array)->data)[0]))DN_CArray2_AddArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), items, count, add) +#define DN_IArray_Add(array, item, add) (decltype(&((array)->data)[0]))DN_CArray2_AddArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), &item, 1, add) +#define DN_IArray_AppendArray(array, items, count) (decltype(&((array)->data)[0]))DN_CArray2_AddArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), items, count, DN_ArrayAdd_Append) +#define DN_IArray_Append(array, item) (decltype(&((array)->data)[0]))DN_CArray2_AddArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), &item, 1, DN_ArrayAdd_Append) +#define DN_IArray_PrependArray(array, items, count) (decltype(&((array)->data)[0]))DN_CArray2_AddArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), items, count, DN_ArrayAdd_Prepend) +#define DN_IArray_Prepend(array, item) (decltype(&((array)->data)[0]))DN_CArray2_AddArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), &item, 1, DN_ArrayAdd_Prepend) +#define DN_IArray_EraseRange(array, begin_index, count, erase) DN_CArray2_EraseRange((array)->data, &(array)->size, sizeof(((array)->data)[0]), begin_index, count, erase) +#define DN_IArray_Erase(array, index, erase) DN_CArray2_EraseRange((array)->data, &(array)->size, sizeof(((array)->data)[0]), index, 1, erase) +#define DN_IArray_InsertArray(array, index, items, count) (decltype(&((array)->data)[0]))DN_CArray2_InsertArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), index, items, count) +#define DN_IArray_Insert(array, index, item, count) (decltype(&((array)->data)[0]))DN_CArray2_InsertArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), index, &item, 1) + +DN_API DN_ArrayEraseResult DN_CArray2_EraseRange (void *data, DN_USize *size, DN_USize elem_size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase); +DN_API void *DN_CArray2_MakeArray (void *data, DN_USize *size, DN_USize max, DN_USize data_size, DN_USize make_size, DN_ZMem z_mem); +DN_API void *DN_CArray2_AddArray (void *data, DN_USize *size, DN_USize max, DN_USize data_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add); +DN_API bool DN_CArray2_Resize (void **data, DN_USize *size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize new_max); +DN_API bool DN_CArray2_Grow (void **data, DN_USize *size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize new_max); +DN_API bool DN_CArray2_GrowIfNeededFromPool (void **data, DN_USize size, DN_USize *max, DN_USize data_size, DN_Pool *pool); +DN_API void *DN_CSLList_Detach (void **link, void **next); + +DN_API bool DN_Ring_HasSpace (DN_Ring const *ring, DN_U64 size); +DN_API bool DN_Ring_HasData (DN_Ring const *ring, DN_U64 size); +DN_API void DN_Ring_Write (DN_Ring *ring, void const *src, DN_U64 src_size); +#define DN_Ring_WriteStruct(ring, item) DN_Ring_Write((ring), (item), sizeof(*(item))) +DN_API void DN_Ring_Read (DN_Ring *ring, void *dest, DN_U64 dest_size); +#define DN_Ring_ReadStruct(ring, dest) DN_Ring_Read((ring), (dest), sizeof(*(dest))) + +template DN_ArrayEraseResult DN_CArray_EraseRange (T *data, DN_USize *size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase); +template T * DN_CArray_MakeArray (T *data, DN_USize *size, DN_USize max, DN_USize count, DN_ZMem z_mem); +template T * DN_CArray_InsertArray (T *data, DN_USize *size, DN_USize max, DN_USize index, T const *items, DN_USize count); +template T DN_CArray_PopFront (T *data, DN_USize *size, DN_USize count); +template T DN_CArray_PopBack (T *data, DN_USize *size, DN_USize count); +template DN_ArrayFindResult DN_CArray_Find (T *data, DN_USize size, T const &value); + +// NOTE: DN_SArray ///////////////////////////////////////////////////////////////////////////////// +#if !defined(DN_NO_SARRAY) +template DN_SArray DN_SArray_Init (DN_Arena *arena, DN_USize size, DN_ZMem z_mem); +template DN_SArray DN_SArray_InitSlice (DN_Arena *arena, DN_Slice slice, DN_USize size, DN_ZMem z_mem); +template DN_SArray DN_SArray_InitCArray (DN_Arena *arena, T const (&array)[N], DN_USize size, DN_ZMem); +template DN_SArray DN_SArray_InitBuffer (T* buffer, DN_USize size); +template bool DN_SArray_IsValid (DN_SArray const *array); +template DN_Slice DN_SArray_Slice (DN_SArray const *array); +template T * DN_SArray_AddArray (DN_SArray *array, T const *items, DN_USize count); +template T * DN_SArray_AddCArray (DN_SArray *array, T const (&items)[N]); +template T * DN_SArray_Add (DN_SArray *array, T const &item); +#define DN_SArray_AddArrayAssert(...) DN_HardAssert(DN_SArray_AddArray(__VA_ARGS__)) +#define DN_SArray_AddCArrayAssert(...) DN_HardAssert(DN_SArray_AddCArray(__VA_ARGS__)) +#define DN_SArray_AddAssert(...) DN_HardAssert(DN_SArray_Add(__VA_ARGS__)) +template T * DN_SArray_MakeArray (DN_SArray *array, DN_USize count, DN_ZMem z_mem); +template T * DN_SArray_Make (DN_SArray *array, DN_ZMem z_mem); +#define DN_SArray_MakeArrayAssert(...) DN_HardAssert(DN_SArray_MakeArray(__VA_ARGS__)) +#define DN_SArray_MakeAssert(...) DN_HardAssert(DN_SArray_Make(__VA_ARGS__)) +template T * DN_SArray_InsertArray (DN_SArray *array, DN_USize index, T const *items, DN_USize count); +template T * DN_SArray_InsertCArray (DN_SArray *array, DN_USize index, T const (&items)[N]); +template T * DN_SArray_Insert (DN_SArray *array, DN_USize index, T const &item); +#define DN_SArray_InsertArrayAssert(...) DN_HardAssert(DN_SArray_InsertArray(__VA_ARGS__)) +#define DN_SArray_InsertCArrayAssert(...) DN_HardAssert(DN_SArray_InsertCArray(__VA_ARGS__)) +#define DN_SArray_InsertAssert(...) DN_HardAssert(DN_SArray_Insert(__VA_ARGS__)) +template T DN_SArray_PopFront (DN_SArray *array, DN_USize count); +template T DN_SArray_PopBack (DN_SArray *array, DN_USize count); +template DN_ArrayEraseResult DN_SArray_EraseRange (DN_SArray *array, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase); +template void DN_SArray_Clear (DN_SArray *array); +#endif // !defined(DN_NO_SARRAY) + +#if !defined(DN_NO_FARRAY) +#define DN_FArray_ToSArray(array) DN_SArray_InitBuffer((array)->data, DN_ArrayCountU((array)->data)) +template DN_FArray DN_FArray_Init (T const *array, DN_USize count); +#define DN_FArray_HasData(array) ((array).data && (array).size) +template DN_FArray DN_FArray_InitSlice (DN_Slice slice); +template DN_FArray DN_FArray_InitCArray (T const (&items)[K]); +template bool DN_FArray_IsValid (DN_FArray const *array); +template DN_USize DN_FArray_Max (DN_FArray const *) { return N; } +template DN_Slice DN_FArray_Slice (DN_FArray const *array); +template T * DN_FArray_AddArray (DN_FArray *array, T const *items, DN_USize count); +template T * DN_FArray_AddCArray (DN_FArray *array, T const (&items)[K]); +template T * DN_FArray_Add (DN_FArray *array, T const &item); +#define DN_FArray_AddArrayAssert(...) DN_HardAssert(DN_FArray_AddArray(__VA_ARGS__)) +#define DN_FArray_AddCArrayAssert(...) DN_HardAssert(DN_FArray_AddCArray(__VA_ARGS__)) +#define DN_FArray_AddAssert(...) DN_HardAssert(DN_FArray_Add(__VA_ARGS__)) +template T * DN_FArray_MakeArray (DN_FArray *array, DN_USize count, DN_ZMem z_mem); +template T * DN_FArray_Make (DN_FArray *array, DN_ZMem z_mem); +#define DN_FArray_MakeArrayAssert(...) DN_HardAssert(DN_FArray_MakeArray(__VA_ARGS__)) +#define DN_FArray_MakeAssert(...) DN_HardAssert(DN_FArray_Make(__VA_ARGS__)) +template T * DN_FArray_InsertArray (DN_FArray *array, T const &item, DN_USize index); +template T * DN_FArray_InsertCArray (DN_FArray *array, DN_USize index, T const (&items)[K]); +template T * DN_FArray_Insert (DN_FArray *array, DN_USize index, T const &item); +#define DN_FArray_InsertArrayAssert(...) DN_HardAssert(DN_FArray_InsertArray(__VA_ARGS__)) +#define DN_FArray_InsertAssert(...) DN_HardAssert(DN_FArray_Insert(__VA_ARGS__)) +template T DN_FArray_PopFront (DN_FArray *array, DN_USize count); +template T DN_FArray_PopBack (DN_FArray *array, DN_USize count); +template DN_ArrayFindResult DN_FArray_Find (DN_FArray *array, T const &find); +template DN_ArrayEraseResult DN_FArray_EraseRange (DN_FArray *array, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase); +template void DN_FArray_Clear (DN_FArray *array); +#endif // !defined(DN_NO_FARRAY) + +#if !defined(DN_NO_SLICE) +#define DN_TO_SLICE(val) DN_Slice_Init((val)->data, (val)->size) +#define DN_Slice_InitCArray(array) DN_Slice_Init(array, DN_ArrayCountU(array)) +template DN_Slice DN_Slice_Init (T* const data, DN_USize size); +template DN_Slice DN_Slice_InitCArrayCopy (DN_Arena *arena, T const (&array)[N]); +template DN_Slice DN_Slice_Copy (DN_Arena *arena, DN_Slice slice); +template DN_Slice DN_Slice_CopyPtr (DN_Arena *arena, T* const data, DN_USize size); +template DN_Slice DN_Slice_Alloc (DN_Arena *arena, DN_USize size, DN_ZMem z_mem); + DN_Str8 DN_Slice_Str8Render (DN_Arena *arena, DN_Slice array, DN_Str8 separator); + DN_Str8 DN_Slice_Str8RenderSpaceSeparated (DN_Arena *arena, DN_Slice array); + DN_Str16 DN_Slice_Str16Render (DN_Arena *arena, DN_Slice array, DN_Str16 separator); + DN_Str16 DN_Slice_Str16RenderSpaceSeparated(DN_Arena *arena, DN_Slice array); +#endif // !defined(DN_NO_SLICE) + +#if !defined(DN_NO_DSMAP) +template DN_DSMap DN_DSMap_Init (DN_Arena *arena, DN_U32 size, DN_DSMapFlags flags); +template void DN_DSMap_Deinit (DN_DSMap *map, DN_ZMem z_mem); +template bool DN_DSMap_IsValid (DN_DSMap const *map); +template DN_U32 DN_DSMap_Hash (DN_DSMap const *map, DN_DSMapKey key); +template DN_U32 DN_DSMap_HashToSlotIndex (DN_DSMap const *map, DN_DSMapKey key); +template DN_DSMapResult DN_DSMap_Find (DN_DSMap const *map, DN_DSMapKey key); +template DN_DSMapResult DN_DSMap_Make (DN_DSMap *map, DN_DSMapKey key); +template DN_DSMapResult DN_DSMap_Set (DN_DSMap *map, DN_DSMapKey key, T const &value); +template DN_DSMapResult DN_DSMap_FindKeyU64 (DN_DSMap const *map, DN_U64 key); +template DN_DSMapResult DN_DSMap_MakeKeyU64 (DN_DSMap *map, DN_U64 key); +template DN_DSMapResult DN_DSMap_SetKeyU64 (DN_DSMap *map, DN_U64 key, T const &value); +template DN_DSMapResult DN_DSMap_FindKeyStr8 (DN_DSMap const *map, DN_Str8 key); +template DN_DSMapResult DN_DSMap_MakeKeyStr8 (DN_DSMap *map, DN_Str8 key); +template DN_DSMapResult DN_DSMap_SetKeyStr8 (DN_DSMap *map, DN_Str8 key, T const &value); +template bool DN_DSMap_Resize (DN_DSMap *map, DN_U32 size); +template bool DN_DSMap_Erase (DN_DSMap *map, DN_DSMapKey key); +template bool DN_DSMap_EraseKeyU64 (DN_DSMap *map, DN_U64 key); +template bool DN_DSMap_EraseKeyStr8 (DN_DSMap *map, DN_Str8 key); +template DN_DSMapKey DN_DSMap_KeyBuffer (DN_DSMap const *map, void const *data, DN_U32 size); +template DN_DSMapKey DN_DSMap_KeyBufferAsU64NoHash (DN_DSMap const *map, void const *data, DN_U32 size); +template DN_DSMapKey DN_DSMap_KeyU64 (DN_DSMap const *map, DN_U64 u64); +template DN_DSMapKey DN_DSMap_KeyStr8 (DN_DSMap const *map, DN_Str8 string); +#define DN_DSMap_KeyCStr8(map, string) DN_DSMap_KeyBuffer(map, string, sizeof((string))/sizeof((string)[0]) - 1) +DN_API DN_DSMapKey DN_DSMap_KeyU64NoHash (DN_U64 u64); +DN_API bool DN_DSMap_KeyEquals (DN_DSMapKey lhs, DN_DSMapKey rhs); +DN_API bool operator== (DN_DSMapKey lhs, DN_DSMapKey rhs); +#endif // !defined(DN_NO_DSMAP) + +#if !defined(DN_NO_LIST) +template DN_List DN_List_Init (DN_USize chunk_size); +template DN_List DN_List_InitCArray (DN_Arena *arena, DN_USize chunk_size, T const (&array)[N]); +template T * DN_List_At (DN_List *list, DN_USize index, DN_ListChunk **at_chunk); +template void DN_List_Clear (DN_List *list); +template bool DN_List_Iterate (DN_List *list, DN_ListIterator *it, DN_USize start_index); +template T * DN_List_MakeArena (DN_List *list, DN_Arena *arena, DN_USize count); +template T * DN_List_MakePool (DN_List *list, DN_Pool *pool, DN_USize count); +template T * DN_List_AddArena (DN_List *list, DN_Arena *arena, T const &value); +template T * DN_List_AddPool (DN_List *list, DN_Pool *pool, T const &value); +template void DN_List_AddListArena (DN_List *list, DN_Arena *arena, DN_List other); +template void DN_List_AddListArena (DN_List *list, DN_Pool *pool, DN_List other); +template DN_Slice DN_List_ToSliceCopy (DN_List const *list, DN_Arena* arena); +#endif // !defined(DN_NO_LIST) +#endif // !defined(DN_CONTAINER_H) +// DN: Single header generator commented out this header => #include "Base/dn_base_leak.h" +// DN: Single header generator commented out this header => #include "../dn_base_inc.h" + +enum DN_LeakAllocFlag +{ + DN_LeakAllocFlag_Freed = 1 << 0, + DN_LeakAllocFlag_LeakPermitted = 1 << 1, +}; + +struct DN_LeakAlloc +{ + void *ptr; // 8 Pointer to the allocation being tracked + DN_USize size; // 16 Size of the allocation + DN_USize freed_size; // 24 Store the size of the allocation when it is freed + DN_Str8 stack_trace; // 40 Stack trace at the point of allocation + DN_Str8 freed_stack_trace; // 56 Stack trace of where the allocation was freed + DN_U16 flags; // 72 Bit flags from `DN_LeakAllocFlag` +}; + +// NOTE: We aim to keep the allocation record as light as possible as memory tracking can get +// expensive. Enforce that there is no unexpected padding. +DN_StaticAssert(sizeof(DN_LeakAlloc) == 64 || sizeof(DN_LeakAlloc) == 32); // NOTE: 64 bit vs 32 bit pointers respectively + +struct DN_LeakTracker +{ + DN_DSMap alloc_table; + DN_TicketMutex alloc_table_mutex; + DN_Arena alloc_table_arena; + DN_U64 alloc_table_bytes_allocated_for_stack_traces; +}; + +DN_API void DN_LeakTrackAlloc_ (DN_LeakTracker *leak, void *ptr, DN_USize size, bool alloc_can_leak); +DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr); +DN_API void DN_LeakDump_ (DN_LeakTracker *leak); + +#if defined(DN_LEAK_TRACKING) +#define DN_LeakTrackAlloc(leak, ptr, size, alloc_can_leak) DN_LeakTrackAlloc_(leak, ptr, size, alloc_can_leak) +#define DN_LeakTrackDealloc(leak, ptr) DN_LeakTrackDealloc_(leak, ptr) +#define DN_LeakDump(leak) DN_LeakDump_(leak) +#else +#define DN_LeakTrackAlloc(leak, ptr, size, alloc_can_leak) do { (void)ptr; (void)size; (void)alloc_can_leak; } while (0) +#define DN_LeakTrackDealloc(leak, ptr) do { (void)ptr; } while (0) +#define DN_LeakDump(leak) do { } while (0) +#endif + + +#endif // !defined(DN_BASE_INC_H) + // DN: Single header generator commented out this header => #include "dn_os_inc.h" +#if !defined(DN_OS_INC_H) +#define DN_OS_INC_H + +#if defined(DN_PLATFORM_WIN32) + // DN: Single header generator commented out this header => #include "OS/dn_os_windows.h" +#if !defined(DN_OS_WINDOWS_H) +#define DN_OS_WINDOWS_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +#if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) + #pragma comment(lib, "bcrypt") + #pragma comment(lib, "winhttp") + #pragma comment(lib, "dbghelp") + #pragma comment(lib, "comdlg32") + #pragma comment(lib, "pathcch") + #pragma comment(lib, "Shell32") // ShellExecuteW + #pragma comment(lib, "shlwapi") +#endif + +#if defined(DN_NO_WINDOWS_H_REPLACEMENT_HEADER) || defined(_INC_WINDOWS) + #define WIN32_LEAN_AND_MEAN + #include // LONG + #include // DN_OS_SecureRNGBytes -> BCryptOpenAlgorithmProvider ... etc + #include // DN_Win_MakeProcessDPIAware -> SetProcessDpiAwareProc + #include // PathRelativePathTO + #include // PathCchCanonicalizeEx + #include // WinHttp* + #include // PROCESS_MEMORY_COUNTERS_EX2 + #include // OPENFILENAMEW + #include +#else + DN_MSVC_WARNING_PUSH + DN_MSVC_WARNING_DISABLE(4201) // warning C4201: nonstandard extension used: nameless struct/union + + // NOTE: basetsd.h ///////////////////////////////////////////////////////////////////////////// + typedef unsigned __int64 ULONG_PTR, *PULONG_PTR; + typedef unsigned __int64 UINT_PTR, *PUINT_PTR; + typedef ULONG_PTR SIZE_T, *PSIZE_T; + typedef __int64 LONG_PTR, *PLONG_PTR; + typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; + typedef unsigned __int64 ULONG64, *PULONG64; + typedef unsigned __int64 DWORD64, *PDWORD64; + + // NOTE: shared/minwindef.h //////////////////////////////////////////////////////////////////// + struct HINSTANCE__ { + int unused; + }; + typedef struct HINSTANCE__ *HINSTANCE; + + typedef unsigned long DWORD; + typedef int BOOL; + typedef int INT; + typedef unsigned long ULONG; + typedef unsigned int UINT; + typedef unsigned short WORD; + typedef unsigned char BYTE; + typedef unsigned char UCHAR; + typedef HINSTANCE HMODULE; /* HMODULEs can be used in place of HINSTANCEs */ + typedef void * HANDLE; + typedef HANDLE HLOCAL; + + typedef unsigned __int64 WPARAM; + typedef LONG_PTR LPARAM; + typedef LONG_PTR LRESULT; + + #define MAX_PATH 260 + + typedef struct _FILETIME { + DWORD dwLowDateTime; + DWORD dwHighDateTime; + } FILETIME, *PFILETIME, *LPFILETIME; + + // NOTE: shared/winerror.h ///////////////////////////////////////////////////////////////////// + // NOTE: GetModuleFileNameW + #define ERROR_INSUFFICIENT_BUFFER 122L // dderror + + // NOTE: um/winnls.h /////////////////////////////////////////////////////////////////////////// + // NOTE: MultiByteToWideChar + #define CP_UTF8 65001 // UTF-8 translation + + // NOTE: um/winnt.h //////////////////////////////////////////////////////////////////////////// + typedef void VOID; + typedef __int64 LONGLONG; + typedef unsigned __int64 ULONGLONG; + typedef void * HANDLE; + typedef char CHAR; + typedef short SHORT; + typedef long LONG; + typedef wchar_t WCHAR; // wc, 16-bit UNICODE character + typedef CHAR * NPSTR, *LPSTR, *PSTR; + typedef WCHAR * NWPSTR, *LPWSTR, *PWSTR; + typedef long HRESULT; + + // NOTE: VirtualAlloc: Allocation Type + #define MEM_RESERVE 0x00002000 + #define MEM_COMMIT 0x00001000 + #define MEM_DECOMMIT 0x00004000 + #define MEM_RELEASE 0x00008000 + + // NOTE: VirtualAlloc: Page Permissions + #define PAGE_NOACCESS 0x01 + #define PAGE_READONLY 0x02 + #define PAGE_READWRITE 0x04 + #define PAGE_GUARD 0x100 + + // NOTE: HeapAlloc + #define HEAP_ZERO_MEMORY 0x00000008 + #define HEAP_NO_SERIALIZE 0x00000001 + #define HEAP_GROWABLE 0x00000002 + #define HEAP_GENERATE_EXCEPTIONS 0x00000004 + #define HEAP_ZERO_MEMORY 0x00000008 + #define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010 + #define HEAP_TAIL_CHECKING_ENABLED 0x00000020 + #define HEAP_FREE_CHECKING_ENABLED 0x00000040 + #define HEAP_DISABLE_COALESCE_ON_FREE 0x00000080 + #define HEAP_CREATE_ALIGN_16 0x00010000 + #define HEAP_CREATE_ENABLE_TRACING 0x00020000 + #define HEAP_CREATE_ENABLE_EXECUTE 0x00040000 + #define HEAP_MAXIMUM_TAG 0x0FFF + #define HEAP_PSEUDO_TAG_FLAG 0x8000 + #define HEAP_TAG_SHIFT 18 + #define HEAP_CREATE_SEGMENT_HEAP 0x00000100 + #define HEAP_CREATE_HARDENED 0x00000200 + + // NOTE: FormatMessageA + #define MAKELANGID(p, s) ((((WORD )(s)) << 10) | (WORD )(p)) + #define LANG_NEUTRAL 0x00 + #define SUBLANG_DEFAULT 0x01 // user default + + // NOTE: CreateFile + #define GENERIC_READ (0x80000000L) + #define GENERIC_WRITE (0x40000000L) + #define GENERIC_EXECUTE (0x20000000L) + #define GENERIC_ALL (0x10000000L) + + #define FILE_APPEND_DATA (0x0004) // file + + // NOTE: CreateFile/FindFirstFile + #define FILE_SHARE_READ 0x00000001 + #define FILE_SHARE_WRITE 0x00000002 + #define FILE_SHARE_DELETE 0x00000004 + + #define FILE_ATTRIBUTE_READONLY 0x00000001 + #define FILE_ATTRIBUTE_HIDDEN 0x00000002 + #define FILE_ATTRIBUTE_SYSTEM 0x00000004 + #define FILE_ATTRIBUTE_DIRECTORY 0x00000010 + #define FILE_ATTRIBUTE_NORMAL 0x00000080 + + // NOTE: STACKFRAME64 + #define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8) + + // NOTE: WaitForSingleObject + #define WAIT_TIMEOUT 258L // dderror + #define STATUS_WAIT_0 ((DWORD )0x00000000L) + #define STATUS_ABANDONED_WAIT_0 ((DWORD )0x00000080L) + + #define S_OK ((HRESULT)0L) + #define S_FALSE ((HRESULT)1L) + + typedef union _ULARGE_INTEGER { + struct { + DWORD LowPart; + DWORD HighPart; + } DUMMYSTRUCTNAME; + struct { + DWORD LowPart; + DWORD HighPart; + } u; + ULONGLONG QuadPart; + } ULARGE_INTEGER; + + typedef union _LARGE_INTEGER { + struct { + DWORD LowPart; + LONG HighPart; + } DUMMYSTRUCTNAME; + struct { + DWORD LowPart; + LONG HighPart; + } u; + LONGLONG QuadPart; + } LARGE_INTEGER; + + typedef struct __declspec(align(16)) _M128A { + ULONGLONG Low; + LONGLONG High; + } M128A, *PM128A; + + typedef struct __declspec(align(16)) _XSAVE_FORMAT { + WORD ControlWord; + WORD StatusWord; + BYTE TagWord; + BYTE Reserved1; + WORD ErrorOpcode; + DWORD ErrorOffset; + WORD ErrorSelector; + WORD Reserved2; + DWORD DataOffset; + WORD DataSelector; + WORD Reserved3; + DWORD MxCsr; + DWORD MxCsr_Mask; + M128A FloatRegisters[8]; + #if defined(_WIN64) + M128A XmmRegisters[16]; + BYTE Reserved4[96]; + #else + M128A XmmRegisters[8]; + BYTE Reserved4[224]; + #endif + } XSAVE_FORMAT, *PXSAVE_FORMAT; + typedef XSAVE_FORMAT XMM_SAVE_AREA32, *PXMM_SAVE_AREA32; + + typedef struct __declspec(align(16)) _CONTEXT { + DWORD64 P1Home; + DWORD64 P2Home; + DWORD64 P3Home; + DWORD64 P4Home; + DWORD64 P5Home; + DWORD64 P6Home; + DWORD ContextFlags; + DWORD MxCsr; + WORD SegCs; + WORD SegDs; + WORD SegEs; + WORD SegFs; + WORD SegGs; + WORD SegSs; + DWORD EFlags; + DWORD64 Dr0; + DWORD64 Dr1; + DWORD64 Dr2; + DWORD64 Dr3; + DWORD64 Dr6; + DWORD64 Dr7; + DWORD64 Rax; + DWORD64 Rcx; + DWORD64 Rdx; + DWORD64 Rbx; + DWORD64 Rsp; + DWORD64 Rbp; + DWORD64 Rsi; + DWORD64 Rdi; + DWORD64 R8; + DWORD64 R9; + DWORD64 R10; + DWORD64 R11; + DWORD64 R12; + DWORD64 R13; + DWORD64 R14; + DWORD64 R15; + DWORD64 Rip; + + union { + XMM_SAVE_AREA32 FltSave; + + struct { + M128A Header[2]; + M128A Legacy[8]; + M128A Xmm0; + M128A Xmm1; + M128A Xmm2; + M128A Xmm3; + M128A Xmm4; + M128A Xmm5; + M128A Xmm6; + M128A Xmm7; + M128A Xmm8; + M128A Xmm9; + M128A Xmm10; + M128A Xmm11; + M128A Xmm12; + M128A Xmm13; + M128A Xmm14; + M128A Xmm15; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + + M128A VectorRegister[26]; + DWORD64 VectorControl; + DWORD64 DebugControl; + DWORD64 LastBranchToRip; + DWORD64 LastBranchFromRip; + DWORD64 LastExceptionToRip; + DWORD64 LastExceptionFromRip; + } CONTEXT; + + typedef struct _LIST_ENTRY { + struct _LIST_ENTRY *Flink; + struct _LIST_ENTRY *Blink; + } LIST_ENTRY, *PLIST_ENTRY, PRLIST_ENTRY; + + typedef struct _RTL_CRITICAL_SECTION_DEBUG { + WORD Type; + WORD CreatorBackTraceIndex; + struct _RTL_CRITICAL_SECTION *CriticalSection; + LIST_ENTRY ProcessLocksList; + DWORD EntryCount; + DWORD ContentionCount; + DWORD Flags; + WORD CreatorBackTraceIndexHigh; + WORD Identifier; + } RTL_CRITICAL_SECTION_DEBUG, *PRTL_CRITICAL_SECTION_DEBUG, RTL_RESOURCE_DEBUG, *PRTL_RESOURCE_DEBUG; + + typedef struct _RTL_CONDITION_VARIABLE { + VOID *Ptr; + } RTL_CONDITION_VARIABLE, *PRTL_CONDITION_VARIABLE; + + #pragma pack(push, 8) + typedef struct _RTL_CRITICAL_SECTION { + PRTL_CRITICAL_SECTION_DEBUG DebugInfo; + + // + // The following three fields control entering and exiting the critical + // section for the resource + // + + LONG LockCount; + LONG RecursionCount; + HANDLE OwningThread; // from the thread's ClientId->UniqueThread + HANDLE LockSemaphore; + ULONG_PTR SpinCount; // force size on 64-bit systems when packed + } RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION; + #pragma pack(pop) + + typedef struct _MODLOAD_DATA { + DWORD ssize; // size of this struct + DWORD ssig; // signature identifying the passed data + VOID *data; // pointer to passed data + DWORD size; // size of passed data + DWORD flags; // options + } MODLOAD_DATA, *PMODLOAD_DATA; + + #define SLMFLAG_VIRTUAL 0x1 + #define SLMFLAG_ALT_INDEX 0x2 + #define SLMFLAG_NO_SYMBOLS 0x4 + + extern "C" + { + __declspec(dllimport) VOID __stdcall RtlCaptureContext(CONTEXT *ContextRecord); + __declspec(dllimport) HANDLE __stdcall GetCurrentProcess(void); + __declspec(dllimport) HANDLE __stdcall GetCurrentThread(void); + __declspec(dllimport) DWORD __stdcall SymSetOptions(DWORD SymOptions); + __declspec(dllimport) BOOL __stdcall SymInitialize(HANDLE hProcess, const CHAR* UserSearchPath, BOOL fInvadeProcess); + __declspec(dllimport) DWORD64 __stdcall SymLoadModuleEx(HANDLE hProcess, HANDLE hFile, CHAR const *ImageName, CHAR const *ModuleName, DWORD64 BaseOfDll, DWORD DllSize, MODLOAD_DATA *Data, DWORD Flags); + __declspec(dllimport) BOOL __stdcall SymUnloadModule64(HANDLE hProcess, DWORD64 BaseOfDll); + } + + // NOTE: um/heapapi.h //////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) HANDLE __stdcall HeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize); + __declspec(dllimport) BOOL __stdcall HeapDestroy(HANDLE hHeap); + __declspec(dllimport) VOID * __stdcall HeapAlloc(HANDLE hHeap, DWORD dwFlags,SIZE_T dwBytes); + __declspec(dllimport) VOID * __stdcall HeapReAlloc(HANDLE hHeap, DWORD dwFlags, VOID *lpMem, SIZE_T dwBytes); + __declspec(dllimport) BOOL __stdcall HeapFree(HANDLE hHeap, DWORD dwFlags, VOID *lpMem); + __declspec(dllimport) SIZE_T __stdcall HeapSize(HANDLE hHeap, DWORD dwFlags, VOID const *lpMem); + __declspec(dllimport) HANDLE __stdcall GetProcessHeap(VOID); + __declspec(dllimport) SIZE_T __stdcall HeapCompact(HANDLE hHeap, DWORD dwFlags); + } + + // NOTE: shared/windef.h //////////////////////////////////////////////////////////////////// + typedef struct tagPOINT + { + LONG x; + LONG y; + } POINT, *PPOINT, *NPPOINT, *LPPOINT; + + // NOTE: handleapi.h /////////////////////////////////////////////////////////////////////////// + #define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1) + + extern "C" + { + __declspec(dllimport) BOOL __stdcall CloseHandle(HANDLE hObject); + } + + // NOTE: consoleapi.h /////////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall WriteConsoleA(HANDLE hConsoleOutput, const VOID* lpBuffer, DWORD nNumberOfCharsToWrite, DWORD *lpNumberOfCharsWritten, VOID *lpReserved); + __declspec(dllimport) BOOL __stdcall AllocConsole(VOID); + __declspec(dllimport) BOOL __stdcall FreeConsole(VOID); + __declspec(dllimport) BOOL __stdcall AttachConsole(DWORD dwProcessId); + __declspec(dllimport) BOOL __stdcall GetConsoleMode(HANDLE hConsoleHandle, DWORD *lpMode); + } + + // NOTE: um/minwinbase.h /////////////////////////////////////////////////////////////////////// + // NOTE: FindFirstFile + #define FIND_FIRST_EX_CASE_SENSITIVE 0x00000001 + #define FIND_FIRST_EX_LARGE_FETCH 0x00000002 + + // NOTE: WaitFor.. + #define WAIT_FAILED ((DWORD)0xFFFFFFFF) + #define WAIT_OBJECT_0 ((STATUS_WAIT_0 ) + 0 ) + #define WAIT_ABANDONED ((STATUS_ABANDONED_WAIT_0 ) + 0 ) + #define WAIT_ABANDONED_0 ((STATUS_ABANDONED_WAIT_0 ) + 0 ) + + // NOTE: CreateProcessW + #define CREATE_UNICODE_ENVIRONMENT 0x00000400 + #define CREATE_NO_WINDOW 0x08000000 + + typedef enum _GET_FILEEX_INFO_LEVELS { + GetFileExInfoStandard, + GetFileExMaxInfoLevel + } GET_FILEEX_INFO_LEVELS; + + typedef struct _SECURITY_ATTRIBUTES { + DWORD nLength; + VOID *lpSecurityDescriptor; + BOOL bInheritHandle; + } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; + + typedef enum _FINDEX_INFO_LEVELS { + FindExInfoStandard, + FindExInfoBasic, + FindExInfoMaxInfoLevel + } FINDEX_INFO_LEVELS; + + typedef enum _FINDEX_SEARCH_OPS { + FindExSearchNameMatch, + FindExSearchLimitToDirectories, + FindExSearchLimitToDevices, + FindExSearchMaxSearchOp + } FINDEX_SEARCH_OPS; + + typedef struct _WIN32_FIND_DATAW { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwReserved0; + DWORD dwReserved1; + WCHAR cFileName[ MAX_PATH ]; + WCHAR cAlternateFileName[ 14 ]; + #ifdef _MAC + DWORD dwFileType; + DWORD dwCreatorType; + WORD wFinderFlags; + #endif + } WIN32_FIND_DATAW, *PWIN32_FIND_DATAW, *LPWIN32_FIND_DATAW; + + typedef struct _SYSTEMTIME { + WORD wYear; + WORD wMonth; + WORD wDayOfWeek; + WORD wDay; + WORD wHour; + WORD wMinute; + WORD wSecond; + WORD wMilliseconds; + } SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME; + + typedef struct _OVERLAPPED { + ULONG_PTR Internal; + ULONG_PTR InternalHigh; + union { + struct { + DWORD Offset; + DWORD OffsetHigh; + } DUMMYSTRUCTNAME; + VOID *Pointer; + } DUMMYUNIONNAME; + + HANDLE hEvent; + } OVERLAPPED, *LPOVERLAPPED; + + typedef RTL_CRITICAL_SECTION CRITICAL_SECTION; + + #define WAIT_FAILED ((DWORD)0xFFFFFFFF) + #define WAIT_OBJECT_0 ((STATUS_WAIT_0 ) + 0 ) + + #define INFINITE 0xFFFFFFFF // Wait/Synchronisation: Infinite timeout + + #define STD_INPUT_HANDLE ((DWORD)-10) + #define STD_OUTPUT_HANDLE ((DWORD)-11) + #define STD_ERROR_HANDLE ((DWORD)-12) + + #define HANDLE_FLAG_INHERIT 0x00000001 + #define HANDLE_FLAG_PROTECT_FROM_CLOSE 0x00000002 + + // NOTE: MoveFile + #define MOVEFILE_REPLACE_EXISTING 0x00000001 + #define MOVEFILE_COPY_ALLOWED 0x00000002 + + // NOTE: FormatMessageA + #define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100 + #define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200 + #define FORMAT_MESSAGE_FROM_HMODULE 0x00000800 + #define FORMAT_MESSAGE_FROM_SYSTEM 0x00001000 + + // NOTE: CreateProcessW + #define STARTF_USESTDHANDLES 0x00000100 + + extern "C" + { + __declspec(dllimport) BOOL __stdcall MoveFileExW (const WCHAR *lpExistingFileName, const WCHAR *lpNewFileName, DWORD dwFlags); + __declspec(dllimport) BOOL __stdcall CopyFileW (const WCHAR *lpExistingFileName, const WCHAR *lpNewFileName, BOOL bFailIfExists); + __declspec(dllimport) HANDLE __stdcall CreateSemaphoreA(SECURITY_ATTRIBUTES *lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, const CHAR *lpName); + __declspec(dllimport) DWORD __stdcall FormatMessageW (DWORD dwFlags, VOID const *lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, va_list *Arguments); + __declspec(dllimport) HLOCAL __stdcall LocalFree (HLOCAL hMem); + } + + // NOTE: um/stringapiset.h ///////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) int __stdcall MultiByteToWideChar(UINT CodePage, DWORD dwFlags, const CHAR *lpMultiByteStr, int cbMultiByte, WCHAR *lpWideCharStr, int cchWideChar); + __declspec(dllimport) int __stdcall WideCharToMultiByte(UINT CodePage, DWORD dwFlags, const WCHAR *lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, const CHAR *lpDefaultChar, BOOL *lpUsedDefaultChar); + } + + // NOTE: um/fileapi.h ////////////////////////////////////////////////////////////////////////// + #define INVALID_FILE_SIZE ((DWORD)0xFFFFFFFF) + #define INVALID_FILE_ATTRIBUTES ((DWORD)-1) + + // NOTE: CreateFile + #define CREATE_NEW 1 + #define CREATE_ALWAYS 2 + #define OPEN_EXISTING 3 + #define OPEN_ALWAYS 4 + #define TRUNCATE_EXISTING 5 + + typedef struct _WIN32_FILE_ATTRIBUTE_DATA { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + } WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall FlushFileBuffers (HANDLE hFile); + __declspec(dllimport) BOOL __stdcall CreateDirectoryW (const WCHAR *lpPathName, SECURITY_ATTRIBUTES *lpSecurityAttributes); + __declspec(dllimport) BOOL __stdcall RemoveDirectoryW (const WCHAR *lpPathName); + __declspec(dllimport) BOOL __stdcall FindNextFileW (HANDLE hFindFile, WIN32_FIND_DATAW *lpFindFileData); + __declspec(dllimport) BOOL __stdcall FindClose (HANDLE hFindFile); + + __declspec(dllimport) HANDLE __stdcall FindFirstFileExW (const WCHAR *lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, VOID *lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, VOID *lpSearchFilter, DWORD dwAdditionalFlags); + __declspec(dllimport) BOOL __stdcall GetFileAttributesExW(const WCHAR *lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, VOID *lpFileInformation); + __declspec(dllimport) BOOL __stdcall GetFileSizeEx (HANDLE hFile, LARGE_INTEGER *lpFileSize); + __declspec(dllimport) BOOL __stdcall DeleteFileW (const WCHAR *lpFileName); + __declspec(dllimport) HANDLE __stdcall CreateFileW (const WCHAR *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, SECURITY_ATTRIBUTES *lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); + __declspec(dllimport) BOOL __stdcall ReadFile (HANDLE hFile, VOID *lpBuffer, DWORD nNumberOfBytesToRead, DWORD *lpNumberOfBytesRead, OVERLAPPED *lpOverlapped); + __declspec(dllimport) BOOL __stdcall WriteFile (HANDLE hFile, const VOID *lpBuffer, DWORD nNumberOfBytesToWrite, DWORD *lpNumberOfBytesWritten, OVERLAPPED *lpOverlapped); + __declspec(dllimport) BOOL __stdcall GetDiskFreeSpaceExW (WCHAR const *lpDirectoryName, ULARGE_INTEGER *lpFreeBytesAvailableToCaller, ULARGE_INTEGER *lpTotalNumberOfBytes, ULARGE_INTEGER *lpTotalNumberOfFreeBytes); + } + + // NOTE: um/processenv.h /////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) DWORD __stdcall GetCurrentDirectoryW (DWORD nBufferLength, WCHAR *lpBuffer); + __declspec(dllimport) HANDLE __stdcall GetStdHandle (DWORD nStdHandle); + __declspec(dllimport) WCHAR* __stdcall GetEnvironmentStringsW (); + __declspec(dllimport) BOOL __stdcall FreeEnvironmentStringsW(WCHAR *penv); + __declspec(dllimport) DWORD __stdcall GetEnvironmentVariableW(WCHAR const *lpName, WCHAR *lpBuffer, DWORD nSize); + __declspec(dllimport) BOOL __stdcall SetEnvironmentVariableW(WCHAR const *lpName, WCHAR const *lpValue); + } + + // NOTE: um/psapi.h //////////////////////////////////////////////////////////////////////////// + typedef struct _PROCESS_MEMORY_COUNTERS { + DWORD cb; + DWORD PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; + } PROCESS_MEMORY_COUNTERS; + typedef PROCESS_MEMORY_COUNTERS *PPROCESS_MEMORY_COUNTERS; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall GetProcessMemoryInfo(HANDLE Process, PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb); + } + + // NOTE: um/sysinfoapi.h /////////////////////////////////////////////////////////////////////// + typedef struct _SYSTEM_INFO { + union { + DWORD dwOemId; // Obsolete field...do not use + struct { + WORD wProcessorArchitecture; + WORD wReserved; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + DWORD dwPageSize; + VOID *lpMinimumApplicationAddress; + VOID *lpMaximumApplicationAddress; + DWORD_PTR dwActiveProcessorMask; + DWORD dwNumberOfProcessors; + DWORD dwProcessorType; + DWORD dwAllocationGranularity; + WORD wProcessorLevel; + WORD wProcessorRevision; + } SYSTEM_INFO, *LPSYSTEM_INFO; + + extern "C" + { + __declspec(dllimport) VOID __stdcall GetSystemInfo(SYSTEM_INFO *lpSystemInfo); + __declspec(dllimport) VOID __stdcall GetSystemTime(SYSTEMTIME *lpSystemTime); + __declspec(dllimport) VOID __stdcall GetSystemTimeAsFileTime(FILETIME *lpSystemTimeAsFileTime); + __declspec(dllimport) VOID __stdcall GetLocalTime(SYSTEMTIME *lpSystemTime); + } + + // NOTE: um/timezoneapi.h ////////////////////////////////////////////////////////////////////// + typedef struct _TIME_ZONE_INFORMATION { + LONG Bias; + WCHAR StandardName[32]; + SYSTEMTIME StandardDate; + LONG StandardBias; + WCHAR DaylightName[32]; + SYSTEMTIME DaylightDate; + LONG DaylightBias; + } TIME_ZONE_INFORMATION, *PTIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall FileTimeToSystemTime (const FILETIME* lpFileTime, SYSTEMTIME *lpSystemTime); + __declspec(dllimport) BOOL __stdcall SystemTimeToFileTime (const SYSTEMTIME* lpSystemTime, FILETIME *lpFileTime); + __declspec(dllimport) BOOL __stdcall TzSpecificLocalTimeToSystemTime(const TIME_ZONE_INFORMATION* lpTimeZoneInformation, const SYSTEMTIME* lpLocalTime, const LPSYSTEMTIME lpUniversalTime); + } + + // NOTE: shared/windef.h /////////////////////////////////////////////////////////////////////// + typedef struct tagRECT { + LONG left; + LONG top; + LONG right; + LONG bottom; + } RECT; + + struct HWND__ { + int unused; + }; + typedef struct HWND__ *HWND; + + struct DPI_AWARENESS_CONTEXT__ { + int unused; + }; + typedef struct DPI_AWARENESS_CONTEXT__ *DPI_AWARENESS_CONTEXT; + + typedef enum DPI_AWARENESS { + DPI_AWARENESS_INVALID = -1, + DPI_AWARENESS_UNAWARE = 0, + DPI_AWARENESS_SYSTEM_AWARE = 1, + DPI_AWARENESS_PER_MONITOR_AWARE = 2 + } DPI_AWARENESS; + + #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4) + + // NOTE: um/winuser.h ////////////////////////////////////////////////////////////////////////// + typedef struct tagWINDOWPLACEMENT { + UINT length; + UINT flags; + UINT showCmd; + POINT ptMinPosition; + POINT ptMaxPosition; + RECT rcNormalPosition; + #ifdef _MAC + RECT rcDevice; + #endif + } WINDOWPLACEMENT; + typedef WINDOWPLACEMENT *PWINDOWPLACEMENT, *LPWINDOWPLACEMENT; + + #define SW_HIDE 0 + #define SW_NORMAL 1 + #define SW_MAXIMIZE 3 + #define SW_SHOWNOACTIVATE 4 + #define SW_SHOW 5 + #define SW_FORCEMINIMIZE 11 + + extern "C" + { + __declspec(dllimport) BOOL __stdcall GetWindowRect (HWND hWnd, RECT *lpRect); + __declspec(dllimport) BOOL __stdcall SetWindowPos (HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags); + __declspec(dllimport) UINT __stdcall GetWindowModuleFileNameA(HWND hwnd, LPSTR pszFileName, UINT cchFileNameMax); + __declspec(dllimport) BOOL __stdcall ShowWindow (HWND hWnd, int nCmdShow); + __declspec(dllimport) BOOL __stdcall GetWindowPlacement (HWND hWnd, WINDOWPLACEMENT *lpwndpl); + + } + + // NOTE: um/wininet.h ////////////////////////////////////////////////////////////////////////// + typedef WORD INTERNET_PORT; + typedef VOID *HINTERNET; + + // NOTE: um/winhttp.h ////////////////////////////////////////////////////////////////////////// + #define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY 0 + #define WINHTTP_ACCESS_TYPE_NO_PROXY 1 + #define WINHTTP_ACCESS_TYPE_NAMED_PROXY 3 + #define WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY 4 + + #define INTERNET_DEFAULT_PORT 0 // use the protocol-specific default + #define INTERNET_DEFAULT_HTTP_PORT 80 // " " HTTP " + #define INTERNET_DEFAULT_HTTPS_PORT 443 // " " HTTPS " + + // NOTE: WinHttpOpen + #define WINHTTP_FLAG_ASYNC 0x10000000 // this session is asynchronous (where supported) + #define WINHTTP_FLAG_SECURE_DEFAULTS 0x30000000 // note that this flag also forces async + + // NOTE: WinHttpOpenRequest + #define WINHTTP_FLAG_SECURE 0x00800000 // use SSL if applicable (HTTPS) + #define WINHTTP_FLAG_ESCAPE_PERCENT 0x00000004 // if escaping enabled, escape percent as well + #define WINHTTP_FLAG_NULL_CODEPAGE 0x00000008 // assume all symbols are ASCII, use fast convertion + #define WINHTTP_FLAG_ESCAPE_DISABLE 0x00000040 // disable escaping + #define WINHTTP_FLAG_ESCAPE_DISABLE_QUERY 0x00000080 // if escaping enabled escape path part, but do not escape query + #define WINHTTP_FLAG_BYPASS_PROXY_CACHE 0x00000100 // add "pragma: no-cache" request header + #define WINHTTP_FLAG_REFRESH WINHTTP_FLAG_BYPASS_PROXY_CACHE + #define WINHTTP_FLAG_AUTOMATIC_CHUNKING 0x00000200 // Send request without content-length header or chunked TE + + #define WINHTTP_NO_PROXY_NAME NULL + #define WINHTTP_NO_PROXY_BYPASS NULL + + // + // WINHTTP_QUERY_FLAG_NUMBER - if this bit is set in the dwInfoLevel parameter of + // HttpQueryHeader(), then the value of the header will be converted to a number + // before being returned to the caller, if applicable + // + #define WINHTTP_QUERY_FLAG_NUMBER 0x20000000 + + #define WINHTTP_QUERY_MIME_VERSION 0 + #define WINHTTP_QUERY_CONTENT_TYPE 1 + #define WINHTTP_QUERY_CONTENT_TRANSFER_ENCODING 2 + #define WINHTTP_QUERY_CONTENT_ID 3 + #define WINHTTP_QUERY_CONTENT_DESCRIPTION 4 + #define WINHTTP_QUERY_CONTENT_LENGTH 5 + #define WINHTTP_QUERY_CONTENT_LANGUAGE 6 + #define WINHTTP_QUERY_ALLOW 7 + #define WINHTTP_QUERY_PUBLIC 8 + #define WINHTTP_QUERY_DATE 9 + #define WINHTTP_QUERY_EXPIRES 10 + #define WINHTTP_QUERY_LAST_MODIFIED 11 + #define WINHTTP_QUERY_MESSAGE_ID 12 + #define WINHTTP_QUERY_URI 13 + #define WINHTTP_QUERY_DERIVED_FROM 14 + #define WINHTTP_QUERY_COST 15 + #define WINHTTP_QUERY_LINK 16 + #define WINHTTP_QUERY_PRAGMA 17 + #define WINHTTP_QUERY_VERSION 18 // special: part of status line + #define WINHTTP_QUERY_STATUS_CODE 19 // special: part of status line + #define WINHTTP_QUERY_STATUS_TEXT 20 // special: part of status line + #define WINHTTP_QUERY_RAW_HEADERS 21 // special: all headers as ASCIIZ + #define WINHTTP_QUERY_RAW_HEADERS_CRLF 22 // special: all headers + #define WINHTTP_QUERY_CONNECTION 23 + #define WINHTTP_QUERY_ACCEPT 24 + #define WINHTTP_QUERY_ACCEPT_CHARSET 25 + #define WINHTTP_QUERY_ACCEPT_ENCODING 26 + #define WINHTTP_QUERY_ACCEPT_LANGUAGE 27 + #define WINHTTP_QUERY_AUTHORIZATION 28 + #define WINHTTP_QUERY_CONTENT_ENCODING 29 + #define WINHTTP_QUERY_FORWARDED 30 + #define WINHTTP_QUERY_FROM 31 + #define WINHTTP_QUERY_IF_MODIFIED_SINCE 32 + #define WINHTTP_QUERY_LOCATION 33 + #define WINHTTP_QUERY_ORIG_URI 34 + #define WINHTTP_QUERY_REFERER 35 + #define WINHTTP_QUERY_RETRY_AFTER 36 + #define WINHTTP_QUERY_SERVER 37 + #define WINHTTP_QUERY_TITLE 38 + #define WINHTTP_QUERY_USER_AGENT 39 + #define WINHTTP_QUERY_WWW_AUTHENTICATE 40 + #define WINHTTP_QUERY_PROXY_AUTHENTICATE 41 + #define WINHTTP_QUERY_ACCEPT_RANGES 42 + #define WINHTTP_QUERY_SET_COOKIE 43 + #define WINHTTP_QUERY_COOKIE 44 + #define WINHTTP_QUERY_REQUEST_METHOD 45 // special: GET/POST etc. + #define WINHTTP_QUERY_REFRESH 46 + #define WINHTTP_QUERY_CONTENT_DISPOSITION 47 + + // NOTE: WinHttpQueryHeaders prettifiers for optional parameters. + #define WINHTTP_HEADER_NAME_BY_INDEX NULL + #define WINHTTP_NO_OUTPUT_BUFFER NULL + #define WINHTTP_NO_HEADER_INDEX NULL + + // NOTE: Http Response Status Codes + #define HTTP_STATUS_CONTINUE 100 // OK to continue with request + #define HTTP_STATUS_SWITCH_PROTOCOLS 101 // server has switched protocols in upgrade header + + #define HTTP_STATUS_OK 200 // request completed + #define HTTP_STATUS_CREATED 201 // object created, reason = new URI + #define HTTP_STATUS_ACCEPTED 202 // async completion (TBS) + #define HTTP_STATUS_PARTIAL 203 // partial completion + #define HTTP_STATUS_NO_CONTENT 204 // no info to return + #define HTTP_STATUS_RESET_CONTENT 205 // request completed, but clear form + #define HTTP_STATUS_PARTIAL_CONTENT 206 // partial GET fulfilled + #define HTTP_STATUS_WEBDAV_MULTI_STATUS 207 // WebDAV Multi-Status + + #define HTTP_STATUS_AMBIGUOUS 300 // server couldn't decide what to return + #define HTTP_STATUS_MOVED 301 // object permanently moved + #define HTTP_STATUS_REDIRECT 302 // object temporarily moved + #define HTTP_STATUS_REDIRECT_METHOD 303 // redirection w/ new access method + #define HTTP_STATUS_NOT_MODIFIED 304 // if-modified-since was not modified + #define HTTP_STATUS_USE_PROXY 305 // redirection to proxy, location header specifies proxy to use + #define HTTP_STATUS_REDIRECT_KEEP_VERB 307 // HTTP/1.1: keep same verb + #define HTTP_STATUS_PERMANENT_REDIRECT 308 // Object permanently moved keep verb + + #define HTTP_STATUS_BAD_REQUEST 400 // invalid syntax + #define HTTP_STATUS_DENIED 401 // access denied + #define HTTP_STATUS_PAYMENT_REQ 402 // payment required + #define HTTP_STATUS_FORBIDDEN 403 // request forbidden + #define HTTP_STATUS_NOT_FOUND 404 // object not found + #define HTTP_STATUS_BAD_METHOD 405 // method is not allowed + #define HTTP_STATUS_NONE_ACCEPTABLE 406 // no response acceptable to client found + #define HTTP_STATUS_PROXY_AUTH_REQ 407 // proxy authentication required + #define HTTP_STATUS_REQUEST_TIMEOUT 408 // server timed out waiting for request + #define HTTP_STATUS_CONFLICT 409 // user should resubmit with more info + #define HTTP_STATUS_GONE 410 // the resource is no longer available + #define HTTP_STATUS_LENGTH_REQUIRED 411 // the server refused to accept request w/o a length + #define HTTP_STATUS_PRECOND_FAILED 412 // precondition given in request failed + #define HTTP_STATUS_REQUEST_TOO_LARGE 413 // request entity was too large + #define HTTP_STATUS_URI_TOO_LONG 414 // request URI too long + #define HTTP_STATUS_UNSUPPORTED_MEDIA 415 // unsupported media type + #define HTTP_STATUS_RETRY_WITH 449 // retry after doing the appropriate action. + + #define HTTP_STATUS_SERVER_ERROR 500 // internal server error + #define HTTP_STATUS_NOT_SUPPORTED 501 // required not supported + #define HTTP_STATUS_BAD_GATEWAY 502 // error response received from gateway + #define HTTP_STATUS_SERVICE_UNAVAIL 503 // temporarily overloaded + #define HTTP_STATUS_GATEWAY_TIMEOUT 504 // timed out waiting for gateway + #define HTTP_STATUS_VERSION_NOT_SUP 505 // HTTP version not supported + + #define HTTP_STATUS_FIRST HTTP_STATUS_CONTINUE + #define HTTP_STATUS_LAST HTTP_STATUS_VERSION_NOT_SUP + + #define WINHTTP_CALLBACK_STATUS_RESOLVING_NAME 0x00000001 + #define WINHTTP_CALLBACK_STATUS_NAME_RESOLVED 0x00000002 + #define WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER 0x00000004 + #define WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER 0x00000008 + #define WINHTTP_CALLBACK_STATUS_SENDING_REQUEST 0x00000010 + #define WINHTTP_CALLBACK_STATUS_REQUEST_SENT 0x00000020 + #define WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE 0x00000040 + #define WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED 0x00000080 + #define WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION 0x00000100 + #define WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED 0x00000200 + #define WINHTTP_CALLBACK_STATUS_HANDLE_CREATED 0x00000400 + #define WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING 0x00000800 + #define WINHTTP_CALLBACK_STATUS_DETECTING_PROXY 0x00001000 + #define WINHTTP_CALLBACK_STATUS_REDIRECT 0x00004000 + #define WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE 0x00008000 + #define WINHTTP_CALLBACK_STATUS_SECURE_FAILURE 0x00010000 + #define WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE 0x00020000 + #define WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE 0x00040000 + #define WINHTTP_CALLBACK_STATUS_READ_COMPLETE 0x00080000 + #define WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE 0x00100000 + #define WINHTTP_CALLBACK_STATUS_REQUEST_ERROR 0x00200000 + #define WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE 0x00400000 + + #define WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE 0x01000000 + #define WINHTTP_CALLBACK_STATUS_CLOSE_COMPLETE 0x02000000 + #define WINHTTP_CALLBACK_STATUS_SHUTDOWN_COMPLETE 0x04000000 + #define WINHTTP_CALLBACK_STATUS_SETTINGS_WRITE_COMPLETE 0x10000000 + #define WINHTTP_CALLBACK_STATUS_SETTINGS_READ_COMPLETE 0x20000000 + + #define WINHTTP_CALLBACK_FLAG_RESOLVE_NAME (WINHTTP_CALLBACK_STATUS_RESOLVING_NAME | WINHTTP_CALLBACK_STATUS_NAME_RESOLVED) + #define WINHTTP_CALLBACK_FLAG_CONNECT_TO_SERVER (WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER | WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER) + #define WINHTTP_CALLBACK_FLAG_SEND_REQUEST (WINHTTP_CALLBACK_STATUS_SENDING_REQUEST | WINHTTP_CALLBACK_STATUS_REQUEST_SENT) + #define WINHTTP_CALLBACK_FLAG_RECEIVE_RESPONSE (WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE | WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED) + #define WINHTTP_CALLBACK_FLAG_CLOSE_CONNECTION (WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION | WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED) + #define WINHTTP_CALLBACK_FLAG_HANDLES (WINHTTP_CALLBACK_STATUS_HANDLE_CREATED | WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING) + #define WINHTTP_CALLBACK_FLAG_DETECTING_PROXY WINHTTP_CALLBACK_STATUS_DETECTING_PROXY + #define WINHTTP_CALLBACK_FLAG_REDIRECT WINHTTP_CALLBACK_STATUS_REDIRECT + #define WINHTTP_CALLBACK_FLAG_INTERMEDIATE_RESPONSE WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE + #define WINHTTP_CALLBACK_FLAG_SECURE_FAILURE WINHTTP_CALLBACK_STATUS_SECURE_FAILURE + #define WINHTTP_CALLBACK_FLAG_SENDREQUEST_COMPLETE WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE + #define WINHTTP_CALLBACK_FLAG_HEADERS_AVAILABLE WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE + #define WINHTTP_CALLBACK_FLAG_DATA_AVAILABLE WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE + #define WINHTTP_CALLBACK_FLAG_READ_COMPLETE WINHTTP_CALLBACK_STATUS_READ_COMPLETE + #define WINHTTP_CALLBACK_FLAG_WRITE_COMPLETE WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE + #define WINHTTP_CALLBACK_FLAG_REQUEST_ERROR WINHTTP_CALLBACK_STATUS_REQUEST_ERROR + + #define WINHTTP_CALLBACK_FLAG_GETPROXYFORURL_COMPLETE WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE + + #define WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS (WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE \ + | WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE \ + | WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE \ + | WINHTTP_CALLBACK_STATUS_READ_COMPLETE \ + | WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE \ + | WINHTTP_CALLBACK_STATUS_REQUEST_ERROR \ + | WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE) + + #define WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS 0xffffffff + #define WINHTTP_INVALID_STATUS_CALLBACK ((WINHTTP_STATUS_CALLBACK)(-1L)) + + typedef struct _WINHTTP_EXTENDED_HEADER + { + union + { + CHAR const *pwszName; + WCHAR const *pszName; + }; + union + { + WCHAR const *pwszValue; + CHAR const *pszValue; + }; + } WINHTTP_EXTENDED_HEADER, *PWINHTTP_EXTENDED_HEADER; + + typedef struct _WINHTTP_ASYNC_RESULT + { + DWORD *dwResult; // indicates which async API has encountered an error + DWORD dwError; // the error code if the API failed + } WINHTTP_ASYNC_RESULT, *LPWINHTTP_ASYNC_RESULT, *PWINHTTP_ASYNC_RESULT; + + typedef + VOID + (*WINHTTP_STATUS_CALLBACK)( + HINTERNET hInternet, + DWORD *dwContext, + DWORD dwInternetStatus, + VOID *lpvStatusInformation, + DWORD dwStatusInformationLength + ); + + extern "C" + { + __declspec(dllimport) HINTERNET __stdcall WinHttpOpen(WCHAR const *pszAgentW, DWORD dwAccessType, WCHAR const *pszProxyW, WCHAR const *pszProxyBypassW, DWORD dwFlags); + __declspec(dllimport) BOOL __stdcall WinHttpCloseHandle(HINTERNET hInternet); + __declspec(dllimport) HINTERNET __stdcall WinHttpConnect(HINTERNET hSession, WCHAR const *pswzServerName, INTERNET_PORT nServerPort, DWORD dwReserved); + __declspec(dllimport) BOOL __stdcall WinHttpReadData(HINTERNET hRequest, VOID *lpBuffer, DWORD dwNumberOfBytesToRead, DWORD *lpdwNumberOfBytesRead); + __declspec(dllimport) HINTERNET __stdcall WinHttpOpenRequest(HINTERNET hConnect, WCHAR const *pwszVerb, WCHAR const *pwszObjectName, WCHAR const *pwszVersion, WCHAR const *pwszReferrer, WCHAR const *ppwszAcceptTypes, DWORD dwFlags); + __declspec(dllimport) BOOL __stdcall WinHttpSendRequest(HINTERNET hRequest, WCHAR const *lpszHeaders, DWORD dwHeadersLength, VOID *lpOptional, DWORD dwOptionalLength, DWORD dwTotalLength, DWORD_PTR dwContext); + __declspec(dllimport) DWORD __stdcall WinHttpAddRequestHeadersEx(HINTERNET hRequest, DWORD dwModifiers, ULONGLONG ullFlags, ULONGLONG ullExtra, DWORD cHeaders, WINHTTP_EXTENDED_HEADER *pHeaders); + __declspec(dllimport) BOOL __stdcall WinHttpSetCredentials(HINTERNET hRequest, // HINTERNET handle returned by WinHttpOpenRequest. + DWORD AuthTargets, // Only WINHTTP_AUTH_TARGET_SERVER and WINHTTP_AUTH_TARGET_PROXY are supported in this version and they are mutually exclusive + DWORD AuthScheme, // must be one of the supported Auth Schemes returned from WinHttpQueryAuthSchemes() + WCHAR * pwszUserName, // 1) NULL if default creds is to be used, in which case pszPassword will be ignored + WCHAR * pwszPassword, // 1) "" == Blank Password; 2)Parameter ignored if pszUserName is NULL; 3) Invalid to pass in NULL if pszUserName is not NULL + VOID * pAuthParams); + __declspec(dllimport) BOOL __stdcall WinHttpQueryHeaders(HINTERNET hRequest, DWORD dwInfoLevel, WCHAR const *pwszName, VOID *lpBuffer, DWORD *lpdwBufferLength, DWORD *lpdwIndex); + __declspec(dllimport) BOOL __stdcall WinHttpReceiveResponse(HINTERNET hRequest, VOID *lpReserved); + __declspec(dllimport) WINHTTP_STATUS_CALLBACK __stdcall WinHttpSetStatusCallback(HINTERNET hInternet, WINHTTP_STATUS_CALLBACK lpfnInternetCallback, DWORD dwNotificationFlags, DWORD_PTR dwReserved); + } + + // NOTE: um/DbgHelp.h ////////////////////////////////////////////////////////////////////////// + #define SYMOPT_CASE_INSENSITIVE 0x00000001 + #define SYMOPT_UNDNAME 0x00000002 + #define SYMOPT_DEFERRED_LOADS 0x00000004 + #define SYMOPT_NO_CPP 0x00000008 + #define SYMOPT_LOAD_LINES 0x00000010 + #define SYMOPT_OMAP_FIND_NEAREST 0x00000020 + #define SYMOPT_LOAD_ANYTHING 0x00000040 + #define SYMOPT_IGNORE_CVREC 0x00000080 + #define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 + #define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 + #define SYMOPT_EXACT_SYMBOLS 0x00000400 + #define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 + #define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 + #define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 + #define SYMOPT_PUBLICS_ONLY 0x00004000 + #define SYMOPT_NO_PUBLICS 0x00008000 + #define SYMOPT_AUTO_PUBLICS 0x00010000 + #define SYMOPT_NO_IMAGE_SEARCH 0x00020000 + #define SYMOPT_SECURE 0x00040000 + #define SYMOPT_NO_PROMPTS 0x00080000 + #define SYMOPT_OVERWRITE 0x00100000 + #define SYMOPT_IGNORE_IMAGEDIR 0x00200000 + #define SYMOPT_FLAT_DIRECTORY 0x00400000 + #define SYMOPT_FAVOR_COMPRESSED 0x00800000 + #define SYMOPT_ALLOW_ZERO_ADDRESS 0x01000000 + #define SYMOPT_DISABLE_SYMSRV_AUTODETECT 0x02000000 + #define SYMOPT_READONLY_CACHE 0x04000000 + #define SYMOPT_SYMPATH_LAST 0x08000000 + #define SYMOPT_DISABLE_FAST_SYMBOLS 0x10000000 + #define SYMOPT_DISABLE_SYMSRV_TIMEOUT 0x20000000 + #define SYMOPT_DISABLE_SRVSTAR_ON_STARTUP 0x40000000 + #define SYMOPT_DEBUG 0x80000000 + + #define MAX_SYM_NAME 2000 + + typedef enum { + AddrMode1616, + AddrMode1632, + AddrModeReal, + AddrModeFlat + } ADDRESS_MODE; + + typedef struct _tagADDRESS64 { + DWORD64 Offset; + WORD Segment; + ADDRESS_MODE Mode; + } ADDRESS64, *LPADDRESS64; + + + typedef struct _KDHELP64 { + DWORD64 Thread; + DWORD ThCallbackStack; + DWORD ThCallbackBStore; + DWORD NextCallback; + DWORD FramePointer; + DWORD64 KiCallUserMode; + DWORD64 KeUserCallbackDispatcher; + DWORD64 SystemRangeStart; + DWORD64 KiUserExceptionDispatcher; + DWORD64 StackBase; + DWORD64 StackLimit; + DWORD BuildVersion; + DWORD RetpolineStubFunctionTableSize; + DWORD64 RetpolineStubFunctionTable; + DWORD RetpolineStubOffset; + DWORD RetpolineStubSize; + DWORD64 Reserved0[2]; + } KDHELP64, *PKDHELP64; + + typedef struct _tagSTACKFRAME64 { + ADDRESS64 AddrPC; // program counter + ADDRESS64 AddrReturn; // return address + ADDRESS64 AddrFrame; // frame pointer + ADDRESS64 AddrStack; // stack pointer + ADDRESS64 AddrBStore; // backing store pointer + VOID *FuncTableEntry; // pointer to pdata/fpo or NULL + DWORD64 Params[4]; // possible arguments to the function + BOOL Far; // WOW far call + BOOL Virtual; // is this a virtual frame? + DWORD64 Reserved[3]; + KDHELP64 KdHelp; + } STACKFRAME64; + + typedef struct _IMAGEHLP_LINEW64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) + VOID *Key; // internal + DWORD LineNumber; // line number in file + WCHAR *FileName; // full filename + DWORD64 Address; // first instruction of line + } IMAGEHLP_LINEW64; + + typedef struct _SYMBOL_INFOW { + ULONG SizeOfStruct; + ULONG TypeIndex; // Type Index of symbol + ULONG64 Reserved[2]; + ULONG Index; + ULONG Size; + ULONG64 ModBase; // Base Address of module comtaining this symbol + ULONG Flags; + ULONG64 Value; // Value of symbol, ValuePresent should be 1 + ULONG64 Address; // Address of symbol including base address of module + ULONG Register; // register holding value or pointer to value + ULONG Scope; // scope of the symbol + ULONG Tag; // pdb classification + ULONG NameLen; // Actual length of name + ULONG MaxNameLen; + WCHAR Name[1]; // Name of symbol + } SYMBOL_INFOW; + + typedef BOOL (__stdcall READ_PROCESS_MEMORY_ROUTINE64)(HANDLE hProcess, DWORD64 qwBaseAddress, VOID *lpBuffer, DWORD nSize, DWORD *lpNumberOfBytesRead); + typedef VOID * (__stdcall FUNCTION_TABLE_ACCESS_ROUTINE64)(HANDLE ahProcess, DWORD64 AddrBase); + typedef DWORD64(__stdcall GET_MODULE_BASE_ROUTINE64)(HANDLE hProcess, DWORD64 Address); + typedef DWORD64(__stdcall TRANSLATE_ADDRESS_ROUTINE64)(HANDLE hProcess, HANDLE hThread, ADDRESS64 *lpaddr); + + extern "C" + { + __declspec(dllimport) BOOL __stdcall StackWalk64 (DWORD MachineType, HANDLE hProcess, HANDLE hThread, STACKFRAME64 *StackFrame, VOID *ContextRecord, READ_PROCESS_MEMORY_ROUTINE64 *ReadMemoryRoutine, FUNCTION_TABLE_ACCESS_ROUTINE64 *FunctionTableAccessRoutine, GET_MODULE_BASE_ROUTINE64 *GetModuleBaseRoutine, TRANSLATE_ADDRESS_ROUTINE64 *TranslateAddress); + __declspec(dllimport) BOOL __stdcall SymFromAddrW (HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, SYMBOL_INFOW *Symbol); + __declspec(dllimport) VOID * __stdcall SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase); + __declspec(dllimport) BOOL __stdcall SymGetLineFromAddrW64 (HANDLE hProcess, DWORD64 dwAddr, DWORD *pdwDisplacement, IMAGEHLP_LINEW64 *Line); + __declspec(dllimport) DWORD64 __stdcall SymGetModuleBase64 (HANDLE hProcess, DWORD64 qwAddr); + __declspec(dllimport) BOOL __stdcall SymRefreshModuleList (HANDLE hProcess); + }; + + // NOTE: um/errhandlingapi.h /////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) DWORD __stdcall GetLastError(VOID); + } + + // NOTE: um/libloaderapi.h ///////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) HMODULE __stdcall LoadLibraryA (const CHAR *lpLibFileName); + __declspec(dllimport) BOOL __stdcall FreeLibrary (HMODULE hLibModule); + __declspec(dllimport) void * __stdcall GetProcAddress (HMODULE hModule, const CHAR *lpProcName); + __declspec(dllimport) HMODULE __stdcall GetModuleHandleA (const CHAR *lpModuleName); + __declspec(dllimport) DWORD __stdcall GetModuleFileNameW(HMODULE hModule, WCHAR *lpFilename, DWORD nSize); + } + + // NOTE: um/synchapi.h ///////////////////////////////////////////////////////////////////////// + typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE; + + extern "C" + { + __declspec(dllimport) VOID __stdcall InitializeConditionVariable (CONDITION_VARIABLE *ConditionVariable); + __declspec(dllimport) VOID __stdcall WakeConditionVariable (CONDITION_VARIABLE *ConditionVariable); + __declspec(dllimport) VOID __stdcall WakeAllConditionVariable (CONDITION_VARIABLE *ConditionVariable); + __declspec(dllimport) BOOL __stdcall SleepConditionVariableCS (CONDITION_VARIABLE *ConditionVariable, CRITICAL_SECTION *CriticalSection, DWORD dwMilliseconds); + + __declspec(dllimport) VOID __stdcall InitializeCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) VOID __stdcall EnterCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) VOID __stdcall LeaveCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) BOOL __stdcall InitializeCriticalSectionAndSpinCount(CRITICAL_SECTION *lpCriticalSection, DWORD dwSpinCount); + __declspec(dllimport) BOOL __stdcall InitializeCriticalSectionEx (CRITICAL_SECTION *lpCriticalSection, DWORD dwSpinCount, DWORD Flags); + __declspec(dllimport) DWORD __stdcall SetCriticalSectionSpinCount (CRITICAL_SECTION *lpCriticalSection, DWORD dwSpinCount); + __declspec(dllimport) BOOL __stdcall TryEnterCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) VOID __stdcall DeleteCriticalSection (CRITICAL_SECTION *lpCriticalSection); + + __declspec(dllimport) DWORD __stdcall WaitForSingleObject (HANDLE hHandle, DWORD dwMilliseconds); + __declspec(dllimport) BOOL __stdcall ReleaseSemaphore (HANDLE hSemaphore, LONG lReleaseCount, LONG *lpPreviousCount); + __declspec(dllimport) VOID __stdcall Sleep (DWORD dwMilliseconds); + } + + // NOTE: um/profileapi.h /////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall QueryPerformanceCounter (LARGE_INTEGER* lpPerformanceCount); + __declspec(dllimport) BOOL __stdcall QueryPerformanceFrequency(LARGE_INTEGER* lpFrequency); + } + + // NOTE: um/processthreadsapi.h //////////////////////////////////////////////////////////////// + typedef struct _PROCESS_INFORMATION { + HANDLE hProcess; + HANDLE hThread; + DWORD dwProcessId; + DWORD dwThreadId; + } PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION; + + typedef struct _STARTUPINFOW { + DWORD cb; + WCHAR *lpReserved; + WCHAR *lpDesktop; + WCHAR *lpTitle; + DWORD dwX; + DWORD dwY; + DWORD dwXSize; + DWORD dwYSize; + DWORD dwXCountChars; + DWORD dwYCountChars; + DWORD dwFillAttribute; + DWORD dwFlags; + WORD wShowWindow; + WORD cbReserved2; + BYTE *lpReserved2; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; + } STARTUPINFOW, *LPSTARTUPINFOW; + + typedef DWORD (__stdcall *PTHREAD_START_ROUTINE)( + VOID *lpThreadParameter + ); + typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall CreateProcessW (WCHAR const *lpApplicationName, WCHAR *lpCommandLine, SECURITY_ATTRIBUTES *lpProcessAttributes, SECURITY_ATTRIBUTES *lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, VOID *lpEnvironment, WCHAR const *lpCurrentDirectory, STARTUPINFOW *lpStartupInfo, PROCESS_INFORMATION *lpProcessInformation); + __declspec(dllimport) HANDLE __stdcall CreateThread (SECURITY_ATTRIBUTES *lpThreadAttributes, SIZE_T dwStackSize, PTHREAD_START_ROUTINE lpStartAddress, VOID *lpParameter, DWORD dwCreationFlags, DWORD *lpThreadId); + __declspec(dllimport) DWORD __stdcall GetCurrentThreadId(VOID); + __declspec(dllimport) BOOL __stdcall GetExitCodeProcess(HANDLE hProcess, DWORD *lpExitCode); + __declspec(dllimport) void __stdcall ExitProcess (UINT uExitCode); + } + + // NOTE: um/memoryapi.h //////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) VOID * __stdcall VirtualAlloc (VOID *lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect); + __declspec(dllimport) BOOL __stdcall VirtualProtect(VOID *lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD *lpflOldProtect); + __declspec(dllimport) BOOL __stdcall VirtualFree (VOID *lpAddress, SIZE_T dwSize, DWORD dwFreeType); + } + + // NOTE: shared/bcrypt.h /////////////////////////////////////////////////////////////////////// + typedef VOID *BCRYPT_ALG_HANDLE; + typedef LONG NTSTATUS; + + extern "C" + { + __declspec(dllimport) NTSTATUS __stdcall BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *phAlgorithm, const WCHAR *pszAlgId, const WCHAR *pszImplementation, ULONG dwFlags); + __declspec(dllimport) NTSTATUS __stdcall BCryptGenRandom (BCRYPT_ALG_HANDLE hAlgorithm, UCHAR *pbBuffer, ULONG cbBuffer, ULONG dwFlags); + } + + // NOTE: um/shellapi.h ///////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) HINSTANCE __stdcall ShellExecuteA(HWND hwnd, CHAR const *lpOperation, CHAR const *lpFile, CHAR const *lpParameters, CHAR const *lpDirectory, INT nShowCmd); + __declspec(dllimport) HINSTANCE __stdcall ShellExecuteW(HWND hwnd, WCHAR const *lpOperation, WCHAR const *lpFile, WCHAR const *lpParameters, WCHAR const *lpDirectory, INT nShowCmd); + } + + // NOTE: um/debugapi.h ///////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall IsDebuggerPresent(); + } + + // NOTE: um/namedpipeapi.h ///////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall CreatePipe (HANDLE *hReadPipe, HANDLE *hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize); + __declspec(dllimport) BOOL __stdcall PeekNamedPipe(HANDLE hNamedPipe, VOID *lpBuffer, DWORD nBufferSize, DWORD *lpBytesRead, DWORD *lpTotalBytesAvail, DWORD *lpBytesLeftThisMessage); + } + + // NOTE: um/handleapi.h //////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall SetHandleInformation(HANDLE hObject, DWORD dwMask, DWORD dwFlags); + } + + // NOTE: um/commdlg.h ////////////////////////////////////////////////////////////////////////// + typedef UINT_PTR (__stdcall *LPOFNHOOKPROC)(HWND, UINT, WPARAM, LPARAM); + typedef struct tagOFNW { + DWORD lStructSize; + HWND hwndOwner; + HINSTANCE hInstance; + WCHAR const * lpstrFilter; + LPWSTR lpstrCustomFilter; + DWORD nMaxCustFilter; + DWORD nFilterIndex; + LPWSTR lpstrFile; + DWORD nMaxFile; + LPWSTR lpstrFileTitle; + DWORD nMaxFileTitle; + WCHAR const * lpstrInitialDir; + WCHAR const * lpstrTitle; + DWORD Flags; + WORD nFileOffset; + WORD nFileExtension; + WCHAR const * lpstrDefExt; + LPARAM lCustData; + LPOFNHOOKPROC lpfnHook; + WCHAR const * lpTemplateName; + #ifdef _MAC + LPEDITMENU lpEditInfo; + LPCSTR lpstrPrompt; + #endif + #if (_WIN32_WINNT >= 0x0500) + void * pvReserved; + DWORD dwReserved; + DWORD FlagsEx; + #endif // (_WIN32_WINNT >= 0x0500) + } OPENFILENAMEW, *LPOPENFILENAMEW; + + + #define OFN_READONLY 0x00000001 + #define OFN_OVERWRITEPROMPT 0x00000002 + #define OFN_HIDEREADONLY 0x00000004 + #define OFN_NOCHANGEDIR 0x00000008 + #define OFN_SHOWHELP 0x00000010 + #define OFN_ENABLEHOOK 0x00000020 + #define OFN_ENABLETEMPLATE 0x00000040 + #define OFN_ENABLETEMPLATEHANDLE 0x00000080 + #define OFN_NOVALIDATE 0x00000100 + #define OFN_ALLOWMULTISELECT 0x00000200 + #define OFN_EXTENSIONDIFFERENT 0x00000400 + #define OFN_PATHMUSTEXIST 0x00000800 + #define OFN_FILEMUSTEXIST 0x00001000 + #define OFN_CREATEPROMPT 0x00002000 + #define OFN_SHAREAWARE 0x00004000 + #define OFN_NOREADONLYRETURN 0x00008000 + #define OFN_NOTESTFILECREATE 0x00010000 + #define OFN_NONETWORKBUTTON 0x00020000 + #define OFN_NOLONGNAMES 0x00040000 // force no long names for 4.x modules + #if(WINVER >= 0x0400) + #define OFN_EXPLORER 0x00080000 // new look commdlg + #define OFN_NODEREFERENCELINKS 0x00100000 + #define OFN_LONGNAMES 0x00200000 // force long names for 3.x modules + // OFN_ENABLEINCLUDENOTIFY and OFN_ENABLESIZING require + // Windows 2000 or higher to have any effect. + #define OFN_ENABLEINCLUDENOTIFY 0x00400000 // send include message to callback + #define OFN_ENABLESIZING 0x00800000 + #endif /* WINVER >= 0x0400 */ + #if (_WIN32_WINNT >= 0x0500) + #define OFN_DONTADDTORECENT 0x02000000 + #define OFN_FORCESHOWHIDDEN 0x10000000 // Show All files including System and hidden files + #endif // (_WIN32_WINNT >= 0x0500) + + //FlagsEx Values + #if (_WIN32_WINNT >= 0x0500) + #define OFN_EX_NOPLACESBAR 0x00000001 + #endif // (_WIN32_WINNT >= 0x0500) + + extern "C" + { + __declspec(dllimport) BOOL __stdcall GetSaveFileNameW(LPOPENFILENAMEW); + __declspec(dllimport) BOOL __stdcall GetOpenFileNameW(LPOPENFILENAMEW); + } + + // NOTE: um/shlwapi.h ////////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall PathRelativePathToW(WCHAR *pszPath, WCHAR const *pszFrom, DWORD dwAttrFrom, WCHAR const *pszTo, DWORD dwAttrTo); + __declspec(dllimport) BOOL __stdcall PathIsRelativeW(WCHAR *pszPath); + } + + // NOTE: um/pathcch.h ////////////////////////////////////////////////////////////////////////// + typedef enum PATHCCH_OPTIONS + { + PATHCCH_NONE = 0x0, + + // This option allows applications to gain access to long paths. It has two + // different behaviors. For process configured to enable long paths it will allow + // the returned path to be longer than the max path limit that is normally imposed. + // For process that are not this option will convert long paths into the extended + // length DOS device form (with \\?\ prefix) when the path is longer than the limit. + // This form is not length limited by the Win32 file system API on all versions of Windows. + // This second behavior is the same behavior for OSes that don't have the long path feature. + // This can not be specified with PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH. + PATHCCH_ALLOW_LONG_PATHS = 0x01, + + // Can only be used when PATHCCH_ALLOW_LONG_PATHS is specified. This + // Forces the API to treat the caller as long path enabled, independent of the + // process's long name enabled state. Cannot be used with PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS. + PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS = 0x02, + + // Can only be used when PATHCCH_ALLOW_LONG_PATHS is specified. This + // Forces the API to treat the caller as long path disabled, independent of the + // process's long name enabled state. Cannot be used with PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS. + PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS = 0x04, + + // Disable the normalization of path segments that includes removing trailing dots and spaces. + // This enables access to paths that win32 path normalization will block. + PATHCCH_DO_NOT_NORMALIZE_SEGMENTS = 0x08, + + // Convert the input path into the extended length DOS device path form (with the \\?\ prefix) + // if not already in that form. This enables access to paths that are otherwise not addressable + // due to Win32 normalization rules (that can strip trailing dots and spaces) and path + // length limitations. This option implies the same behavior of PATHCCH_DO_NOT_NORMALIZE_SEGMENTS. + // This can not be specified with PATHCCH_ALLOW_LONG_PATHS. + PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH = 0x10, + + // When combining or normalizing a path ensure there is a trailing backslash. + PATHCCH_ENSURE_TRAILING_SLASH = 0x020, + + // Convert forward slashes to back slashes and collapse multiple slashes. + // This is needed to to support sub-path or identity comparisons. + PATHCCH_CANONICALIZE_SLASHES = 0x040, + } PATHCCH_OPTIONS; + + extern "C" + { + __declspec(dllimport) HRESULT __stdcall PathCchCanonicalizeEx(PWSTR pszPathOut, size_t cchPathOut, WCHAR const *pszPathIn, ULONG dwFlags); + }; + + // NOTE: um/errhandlingapi.h /////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) VOID __stdcall RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const ULONG_PTR* lpArguments); + }; + + // NOTE: include/excpt.h /////////////////////////////////////////////////////////////////// + #define EXCEPTION_EXECUTE_HANDLER 1 + #define EXCEPTION_CONTINUE_SEARCH 0 + #define EXCEPTION_CONTINUE_EXECUTION (-1) + + DN_MSVC_WARNING_POP +#endif // !defined(_INC_WINDOWS) +#endif // !defined(DN_OS_WINDOWS_H) + // DN: Single header generator commented out this header => #include "OS/dn_os_w32.h" +#if !defined(DN_OS_WIN32_H) +#define DN_OS_WIN32_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" + // DN: Single header generator commented out this header => #include "dn_os_windows.h" +#if !defined(DN_OS_WINDOWS_H) +#define DN_OS_WINDOWS_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +#if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) + #pragma comment(lib, "bcrypt") + #pragma comment(lib, "winhttp") + #pragma comment(lib, "dbghelp") + #pragma comment(lib, "comdlg32") + #pragma comment(lib, "pathcch") + #pragma comment(lib, "Shell32") // ShellExecuteW + #pragma comment(lib, "shlwapi") +#endif + +#if defined(DN_NO_WINDOWS_H_REPLACEMENT_HEADER) || defined(_INC_WINDOWS) + #define WIN32_LEAN_AND_MEAN + #include // LONG + #include // DN_OS_SecureRNGBytes -> BCryptOpenAlgorithmProvider ... etc + #include // DN_Win_MakeProcessDPIAware -> SetProcessDpiAwareProc + #include // PathRelativePathTO + #include // PathCchCanonicalizeEx + #include // WinHttp* + #include // PROCESS_MEMORY_COUNTERS_EX2 + #include // OPENFILENAMEW + #include +#else + DN_MSVC_WARNING_PUSH + DN_MSVC_WARNING_DISABLE(4201) // warning C4201: nonstandard extension used: nameless struct/union + + // NOTE: basetsd.h ///////////////////////////////////////////////////////////////////////////// + typedef unsigned __int64 ULONG_PTR, *PULONG_PTR; + typedef unsigned __int64 UINT_PTR, *PUINT_PTR; + typedef ULONG_PTR SIZE_T, *PSIZE_T; + typedef __int64 LONG_PTR, *PLONG_PTR; + typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; + typedef unsigned __int64 ULONG64, *PULONG64; + typedef unsigned __int64 DWORD64, *PDWORD64; + + // NOTE: shared/minwindef.h //////////////////////////////////////////////////////////////////// + struct HINSTANCE__ { + int unused; + }; + typedef struct HINSTANCE__ *HINSTANCE; + + typedef unsigned long DWORD; + typedef int BOOL; + typedef int INT; + typedef unsigned long ULONG; + typedef unsigned int UINT; + typedef unsigned short WORD; + typedef unsigned char BYTE; + typedef unsigned char UCHAR; + typedef HINSTANCE HMODULE; /* HMODULEs can be used in place of HINSTANCEs */ + typedef void * HANDLE; + typedef HANDLE HLOCAL; + + typedef unsigned __int64 WPARAM; + typedef LONG_PTR LPARAM; + typedef LONG_PTR LRESULT; + + #define MAX_PATH 260 + + typedef struct _FILETIME { + DWORD dwLowDateTime; + DWORD dwHighDateTime; + } FILETIME, *PFILETIME, *LPFILETIME; + + // NOTE: shared/winerror.h ///////////////////////////////////////////////////////////////////// + // NOTE: GetModuleFileNameW + #define ERROR_INSUFFICIENT_BUFFER 122L // dderror + + // NOTE: um/winnls.h /////////////////////////////////////////////////////////////////////////// + // NOTE: MultiByteToWideChar + #define CP_UTF8 65001 // UTF-8 translation + + // NOTE: um/winnt.h //////////////////////////////////////////////////////////////////////////// + typedef void VOID; + typedef __int64 LONGLONG; + typedef unsigned __int64 ULONGLONG; + typedef void * HANDLE; + typedef char CHAR; + typedef short SHORT; + typedef long LONG; + typedef wchar_t WCHAR; // wc, 16-bit UNICODE character + typedef CHAR * NPSTR, *LPSTR, *PSTR; + typedef WCHAR * NWPSTR, *LPWSTR, *PWSTR; + typedef long HRESULT; + + // NOTE: VirtualAlloc: Allocation Type + #define MEM_RESERVE 0x00002000 + #define MEM_COMMIT 0x00001000 + #define MEM_DECOMMIT 0x00004000 + #define MEM_RELEASE 0x00008000 + + // NOTE: VirtualAlloc: Page Permissions + #define PAGE_NOACCESS 0x01 + #define PAGE_READONLY 0x02 + #define PAGE_READWRITE 0x04 + #define PAGE_GUARD 0x100 + + // NOTE: HeapAlloc + #define HEAP_ZERO_MEMORY 0x00000008 + #define HEAP_NO_SERIALIZE 0x00000001 + #define HEAP_GROWABLE 0x00000002 + #define HEAP_GENERATE_EXCEPTIONS 0x00000004 + #define HEAP_ZERO_MEMORY 0x00000008 + #define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010 + #define HEAP_TAIL_CHECKING_ENABLED 0x00000020 + #define HEAP_FREE_CHECKING_ENABLED 0x00000040 + #define HEAP_DISABLE_COALESCE_ON_FREE 0x00000080 + #define HEAP_CREATE_ALIGN_16 0x00010000 + #define HEAP_CREATE_ENABLE_TRACING 0x00020000 + #define HEAP_CREATE_ENABLE_EXECUTE 0x00040000 + #define HEAP_MAXIMUM_TAG 0x0FFF + #define HEAP_PSEUDO_TAG_FLAG 0x8000 + #define HEAP_TAG_SHIFT 18 + #define HEAP_CREATE_SEGMENT_HEAP 0x00000100 + #define HEAP_CREATE_HARDENED 0x00000200 + + // NOTE: FormatMessageA + #define MAKELANGID(p, s) ((((WORD )(s)) << 10) | (WORD )(p)) + #define LANG_NEUTRAL 0x00 + #define SUBLANG_DEFAULT 0x01 // user default + + // NOTE: CreateFile + #define GENERIC_READ (0x80000000L) + #define GENERIC_WRITE (0x40000000L) + #define GENERIC_EXECUTE (0x20000000L) + #define GENERIC_ALL (0x10000000L) + + #define FILE_APPEND_DATA (0x0004) // file + + // NOTE: CreateFile/FindFirstFile + #define FILE_SHARE_READ 0x00000001 + #define FILE_SHARE_WRITE 0x00000002 + #define FILE_SHARE_DELETE 0x00000004 + + #define FILE_ATTRIBUTE_READONLY 0x00000001 + #define FILE_ATTRIBUTE_HIDDEN 0x00000002 + #define FILE_ATTRIBUTE_SYSTEM 0x00000004 + #define FILE_ATTRIBUTE_DIRECTORY 0x00000010 + #define FILE_ATTRIBUTE_NORMAL 0x00000080 + + // NOTE: STACKFRAME64 + #define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8) + + // NOTE: WaitForSingleObject + #define WAIT_TIMEOUT 258L // dderror + #define STATUS_WAIT_0 ((DWORD )0x00000000L) + #define STATUS_ABANDONED_WAIT_0 ((DWORD )0x00000080L) + + #define S_OK ((HRESULT)0L) + #define S_FALSE ((HRESULT)1L) + + typedef union _ULARGE_INTEGER { + struct { + DWORD LowPart; + DWORD HighPart; + } DUMMYSTRUCTNAME; + struct { + DWORD LowPart; + DWORD HighPart; + } u; + ULONGLONG QuadPart; + } ULARGE_INTEGER; + + typedef union _LARGE_INTEGER { + struct { + DWORD LowPart; + LONG HighPart; + } DUMMYSTRUCTNAME; + struct { + DWORD LowPart; + LONG HighPart; + } u; + LONGLONG QuadPart; + } LARGE_INTEGER; + + typedef struct __declspec(align(16)) _M128A { + ULONGLONG Low; + LONGLONG High; + } M128A, *PM128A; + + typedef struct __declspec(align(16)) _XSAVE_FORMAT { + WORD ControlWord; + WORD StatusWord; + BYTE TagWord; + BYTE Reserved1; + WORD ErrorOpcode; + DWORD ErrorOffset; + WORD ErrorSelector; + WORD Reserved2; + DWORD DataOffset; + WORD DataSelector; + WORD Reserved3; + DWORD MxCsr; + DWORD MxCsr_Mask; + M128A FloatRegisters[8]; + #if defined(_WIN64) + M128A XmmRegisters[16]; + BYTE Reserved4[96]; + #else + M128A XmmRegisters[8]; + BYTE Reserved4[224]; + #endif + } XSAVE_FORMAT, *PXSAVE_FORMAT; + typedef XSAVE_FORMAT XMM_SAVE_AREA32, *PXMM_SAVE_AREA32; + + typedef struct __declspec(align(16)) _CONTEXT { + DWORD64 P1Home; + DWORD64 P2Home; + DWORD64 P3Home; + DWORD64 P4Home; + DWORD64 P5Home; + DWORD64 P6Home; + DWORD ContextFlags; + DWORD MxCsr; + WORD SegCs; + WORD SegDs; + WORD SegEs; + WORD SegFs; + WORD SegGs; + WORD SegSs; + DWORD EFlags; + DWORD64 Dr0; + DWORD64 Dr1; + DWORD64 Dr2; + DWORD64 Dr3; + DWORD64 Dr6; + DWORD64 Dr7; + DWORD64 Rax; + DWORD64 Rcx; + DWORD64 Rdx; + DWORD64 Rbx; + DWORD64 Rsp; + DWORD64 Rbp; + DWORD64 Rsi; + DWORD64 Rdi; + DWORD64 R8; + DWORD64 R9; + DWORD64 R10; + DWORD64 R11; + DWORD64 R12; + DWORD64 R13; + DWORD64 R14; + DWORD64 R15; + DWORD64 Rip; + + union { + XMM_SAVE_AREA32 FltSave; + + struct { + M128A Header[2]; + M128A Legacy[8]; + M128A Xmm0; + M128A Xmm1; + M128A Xmm2; + M128A Xmm3; + M128A Xmm4; + M128A Xmm5; + M128A Xmm6; + M128A Xmm7; + M128A Xmm8; + M128A Xmm9; + M128A Xmm10; + M128A Xmm11; + M128A Xmm12; + M128A Xmm13; + M128A Xmm14; + M128A Xmm15; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + + M128A VectorRegister[26]; + DWORD64 VectorControl; + DWORD64 DebugControl; + DWORD64 LastBranchToRip; + DWORD64 LastBranchFromRip; + DWORD64 LastExceptionToRip; + DWORD64 LastExceptionFromRip; + } CONTEXT; + + typedef struct _LIST_ENTRY { + struct _LIST_ENTRY *Flink; + struct _LIST_ENTRY *Blink; + } LIST_ENTRY, *PLIST_ENTRY, PRLIST_ENTRY; + + typedef struct _RTL_CRITICAL_SECTION_DEBUG { + WORD Type; + WORD CreatorBackTraceIndex; + struct _RTL_CRITICAL_SECTION *CriticalSection; + LIST_ENTRY ProcessLocksList; + DWORD EntryCount; + DWORD ContentionCount; + DWORD Flags; + WORD CreatorBackTraceIndexHigh; + WORD Identifier; + } RTL_CRITICAL_SECTION_DEBUG, *PRTL_CRITICAL_SECTION_DEBUG, RTL_RESOURCE_DEBUG, *PRTL_RESOURCE_DEBUG; + + typedef struct _RTL_CONDITION_VARIABLE { + VOID *Ptr; + } RTL_CONDITION_VARIABLE, *PRTL_CONDITION_VARIABLE; + + #pragma pack(push, 8) + typedef struct _RTL_CRITICAL_SECTION { + PRTL_CRITICAL_SECTION_DEBUG DebugInfo; + + // + // The following three fields control entering and exiting the critical + // section for the resource + // + + LONG LockCount; + LONG RecursionCount; + HANDLE OwningThread; // from the thread's ClientId->UniqueThread + HANDLE LockSemaphore; + ULONG_PTR SpinCount; // force size on 64-bit systems when packed + } RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION; + #pragma pack(pop) + + typedef struct _MODLOAD_DATA { + DWORD ssize; // size of this struct + DWORD ssig; // signature identifying the passed data + VOID *data; // pointer to passed data + DWORD size; // size of passed data + DWORD flags; // options + } MODLOAD_DATA, *PMODLOAD_DATA; + + #define SLMFLAG_VIRTUAL 0x1 + #define SLMFLAG_ALT_INDEX 0x2 + #define SLMFLAG_NO_SYMBOLS 0x4 + + extern "C" + { + __declspec(dllimport) VOID __stdcall RtlCaptureContext(CONTEXT *ContextRecord); + __declspec(dllimport) HANDLE __stdcall GetCurrentProcess(void); + __declspec(dllimport) HANDLE __stdcall GetCurrentThread(void); + __declspec(dllimport) DWORD __stdcall SymSetOptions(DWORD SymOptions); + __declspec(dllimport) BOOL __stdcall SymInitialize(HANDLE hProcess, const CHAR* UserSearchPath, BOOL fInvadeProcess); + __declspec(dllimport) DWORD64 __stdcall SymLoadModuleEx(HANDLE hProcess, HANDLE hFile, CHAR const *ImageName, CHAR const *ModuleName, DWORD64 BaseOfDll, DWORD DllSize, MODLOAD_DATA *Data, DWORD Flags); + __declspec(dllimport) BOOL __stdcall SymUnloadModule64(HANDLE hProcess, DWORD64 BaseOfDll); + } + + // NOTE: um/heapapi.h //////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) HANDLE __stdcall HeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize); + __declspec(dllimport) BOOL __stdcall HeapDestroy(HANDLE hHeap); + __declspec(dllimport) VOID * __stdcall HeapAlloc(HANDLE hHeap, DWORD dwFlags,SIZE_T dwBytes); + __declspec(dllimport) VOID * __stdcall HeapReAlloc(HANDLE hHeap, DWORD dwFlags, VOID *lpMem, SIZE_T dwBytes); + __declspec(dllimport) BOOL __stdcall HeapFree(HANDLE hHeap, DWORD dwFlags, VOID *lpMem); + __declspec(dllimport) SIZE_T __stdcall HeapSize(HANDLE hHeap, DWORD dwFlags, VOID const *lpMem); + __declspec(dllimport) HANDLE __stdcall GetProcessHeap(VOID); + __declspec(dllimport) SIZE_T __stdcall HeapCompact(HANDLE hHeap, DWORD dwFlags); + } + + // NOTE: shared/windef.h //////////////////////////////////////////////////////////////////// + typedef struct tagPOINT + { + LONG x; + LONG y; + } POINT, *PPOINT, *NPPOINT, *LPPOINT; + + // NOTE: handleapi.h /////////////////////////////////////////////////////////////////////////// + #define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1) + + extern "C" + { + __declspec(dllimport) BOOL __stdcall CloseHandle(HANDLE hObject); + } + + // NOTE: consoleapi.h /////////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall WriteConsoleA(HANDLE hConsoleOutput, const VOID* lpBuffer, DWORD nNumberOfCharsToWrite, DWORD *lpNumberOfCharsWritten, VOID *lpReserved); + __declspec(dllimport) BOOL __stdcall AllocConsole(VOID); + __declspec(dllimport) BOOL __stdcall FreeConsole(VOID); + __declspec(dllimport) BOOL __stdcall AttachConsole(DWORD dwProcessId); + __declspec(dllimport) BOOL __stdcall GetConsoleMode(HANDLE hConsoleHandle, DWORD *lpMode); + } + + // NOTE: um/minwinbase.h /////////////////////////////////////////////////////////////////////// + // NOTE: FindFirstFile + #define FIND_FIRST_EX_CASE_SENSITIVE 0x00000001 + #define FIND_FIRST_EX_LARGE_FETCH 0x00000002 + + // NOTE: WaitFor.. + #define WAIT_FAILED ((DWORD)0xFFFFFFFF) + #define WAIT_OBJECT_0 ((STATUS_WAIT_0 ) + 0 ) + #define WAIT_ABANDONED ((STATUS_ABANDONED_WAIT_0 ) + 0 ) + #define WAIT_ABANDONED_0 ((STATUS_ABANDONED_WAIT_0 ) + 0 ) + + // NOTE: CreateProcessW + #define CREATE_UNICODE_ENVIRONMENT 0x00000400 + #define CREATE_NO_WINDOW 0x08000000 + + typedef enum _GET_FILEEX_INFO_LEVELS { + GetFileExInfoStandard, + GetFileExMaxInfoLevel + } GET_FILEEX_INFO_LEVELS; + + typedef struct _SECURITY_ATTRIBUTES { + DWORD nLength; + VOID *lpSecurityDescriptor; + BOOL bInheritHandle; + } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; + + typedef enum _FINDEX_INFO_LEVELS { + FindExInfoStandard, + FindExInfoBasic, + FindExInfoMaxInfoLevel + } FINDEX_INFO_LEVELS; + + typedef enum _FINDEX_SEARCH_OPS { + FindExSearchNameMatch, + FindExSearchLimitToDirectories, + FindExSearchLimitToDevices, + FindExSearchMaxSearchOp + } FINDEX_SEARCH_OPS; + + typedef struct _WIN32_FIND_DATAW { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwReserved0; + DWORD dwReserved1; + WCHAR cFileName[ MAX_PATH ]; + WCHAR cAlternateFileName[ 14 ]; + #ifdef _MAC + DWORD dwFileType; + DWORD dwCreatorType; + WORD wFinderFlags; + #endif + } WIN32_FIND_DATAW, *PWIN32_FIND_DATAW, *LPWIN32_FIND_DATAW; + + typedef struct _SYSTEMTIME { + WORD wYear; + WORD wMonth; + WORD wDayOfWeek; + WORD wDay; + WORD wHour; + WORD wMinute; + WORD wSecond; + WORD wMilliseconds; + } SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME; + + typedef struct _OVERLAPPED { + ULONG_PTR Internal; + ULONG_PTR InternalHigh; + union { + struct { + DWORD Offset; + DWORD OffsetHigh; + } DUMMYSTRUCTNAME; + VOID *Pointer; + } DUMMYUNIONNAME; + + HANDLE hEvent; + } OVERLAPPED, *LPOVERLAPPED; + + typedef RTL_CRITICAL_SECTION CRITICAL_SECTION; + + #define WAIT_FAILED ((DWORD)0xFFFFFFFF) + #define WAIT_OBJECT_0 ((STATUS_WAIT_0 ) + 0 ) + + #define INFINITE 0xFFFFFFFF // Wait/Synchronisation: Infinite timeout + + #define STD_INPUT_HANDLE ((DWORD)-10) + #define STD_OUTPUT_HANDLE ((DWORD)-11) + #define STD_ERROR_HANDLE ((DWORD)-12) + + #define HANDLE_FLAG_INHERIT 0x00000001 + #define HANDLE_FLAG_PROTECT_FROM_CLOSE 0x00000002 + + // NOTE: MoveFile + #define MOVEFILE_REPLACE_EXISTING 0x00000001 + #define MOVEFILE_COPY_ALLOWED 0x00000002 + + // NOTE: FormatMessageA + #define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100 + #define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200 + #define FORMAT_MESSAGE_FROM_HMODULE 0x00000800 + #define FORMAT_MESSAGE_FROM_SYSTEM 0x00001000 + + // NOTE: CreateProcessW + #define STARTF_USESTDHANDLES 0x00000100 + + extern "C" + { + __declspec(dllimport) BOOL __stdcall MoveFileExW (const WCHAR *lpExistingFileName, const WCHAR *lpNewFileName, DWORD dwFlags); + __declspec(dllimport) BOOL __stdcall CopyFileW (const WCHAR *lpExistingFileName, const WCHAR *lpNewFileName, BOOL bFailIfExists); + __declspec(dllimport) HANDLE __stdcall CreateSemaphoreA(SECURITY_ATTRIBUTES *lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, const CHAR *lpName); + __declspec(dllimport) DWORD __stdcall FormatMessageW (DWORD dwFlags, VOID const *lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, va_list *Arguments); + __declspec(dllimport) HLOCAL __stdcall LocalFree (HLOCAL hMem); + } + + // NOTE: um/stringapiset.h ///////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) int __stdcall MultiByteToWideChar(UINT CodePage, DWORD dwFlags, const CHAR *lpMultiByteStr, int cbMultiByte, WCHAR *lpWideCharStr, int cchWideChar); + __declspec(dllimport) int __stdcall WideCharToMultiByte(UINT CodePage, DWORD dwFlags, const WCHAR *lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, const CHAR *lpDefaultChar, BOOL *lpUsedDefaultChar); + } + + // NOTE: um/fileapi.h ////////////////////////////////////////////////////////////////////////// + #define INVALID_FILE_SIZE ((DWORD)0xFFFFFFFF) + #define INVALID_FILE_ATTRIBUTES ((DWORD)-1) + + // NOTE: CreateFile + #define CREATE_NEW 1 + #define CREATE_ALWAYS 2 + #define OPEN_EXISTING 3 + #define OPEN_ALWAYS 4 + #define TRUNCATE_EXISTING 5 + + typedef struct _WIN32_FILE_ATTRIBUTE_DATA { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + } WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall FlushFileBuffers (HANDLE hFile); + __declspec(dllimport) BOOL __stdcall CreateDirectoryW (const WCHAR *lpPathName, SECURITY_ATTRIBUTES *lpSecurityAttributes); + __declspec(dllimport) BOOL __stdcall RemoveDirectoryW (const WCHAR *lpPathName); + __declspec(dllimport) BOOL __stdcall FindNextFileW (HANDLE hFindFile, WIN32_FIND_DATAW *lpFindFileData); + __declspec(dllimport) BOOL __stdcall FindClose (HANDLE hFindFile); + + __declspec(dllimport) HANDLE __stdcall FindFirstFileExW (const WCHAR *lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, VOID *lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, VOID *lpSearchFilter, DWORD dwAdditionalFlags); + __declspec(dllimport) BOOL __stdcall GetFileAttributesExW(const WCHAR *lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, VOID *lpFileInformation); + __declspec(dllimport) BOOL __stdcall GetFileSizeEx (HANDLE hFile, LARGE_INTEGER *lpFileSize); + __declspec(dllimport) BOOL __stdcall DeleteFileW (const WCHAR *lpFileName); + __declspec(dllimport) HANDLE __stdcall CreateFileW (const WCHAR *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, SECURITY_ATTRIBUTES *lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); + __declspec(dllimport) BOOL __stdcall ReadFile (HANDLE hFile, VOID *lpBuffer, DWORD nNumberOfBytesToRead, DWORD *lpNumberOfBytesRead, OVERLAPPED *lpOverlapped); + __declspec(dllimport) BOOL __stdcall WriteFile (HANDLE hFile, const VOID *lpBuffer, DWORD nNumberOfBytesToWrite, DWORD *lpNumberOfBytesWritten, OVERLAPPED *lpOverlapped); + __declspec(dllimport) BOOL __stdcall GetDiskFreeSpaceExW (WCHAR const *lpDirectoryName, ULARGE_INTEGER *lpFreeBytesAvailableToCaller, ULARGE_INTEGER *lpTotalNumberOfBytes, ULARGE_INTEGER *lpTotalNumberOfFreeBytes); + } + + // NOTE: um/processenv.h /////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) DWORD __stdcall GetCurrentDirectoryW (DWORD nBufferLength, WCHAR *lpBuffer); + __declspec(dllimport) HANDLE __stdcall GetStdHandle (DWORD nStdHandle); + __declspec(dllimport) WCHAR* __stdcall GetEnvironmentStringsW (); + __declspec(dllimport) BOOL __stdcall FreeEnvironmentStringsW(WCHAR *penv); + __declspec(dllimport) DWORD __stdcall GetEnvironmentVariableW(WCHAR const *lpName, WCHAR *lpBuffer, DWORD nSize); + __declspec(dllimport) BOOL __stdcall SetEnvironmentVariableW(WCHAR const *lpName, WCHAR const *lpValue); + } + + // NOTE: um/psapi.h //////////////////////////////////////////////////////////////////////////// + typedef struct _PROCESS_MEMORY_COUNTERS { + DWORD cb; + DWORD PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; + } PROCESS_MEMORY_COUNTERS; + typedef PROCESS_MEMORY_COUNTERS *PPROCESS_MEMORY_COUNTERS; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall GetProcessMemoryInfo(HANDLE Process, PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb); + } + + // NOTE: um/sysinfoapi.h /////////////////////////////////////////////////////////////////////// + typedef struct _SYSTEM_INFO { + union { + DWORD dwOemId; // Obsolete field...do not use + struct { + WORD wProcessorArchitecture; + WORD wReserved; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + DWORD dwPageSize; + VOID *lpMinimumApplicationAddress; + VOID *lpMaximumApplicationAddress; + DWORD_PTR dwActiveProcessorMask; + DWORD dwNumberOfProcessors; + DWORD dwProcessorType; + DWORD dwAllocationGranularity; + WORD wProcessorLevel; + WORD wProcessorRevision; + } SYSTEM_INFO, *LPSYSTEM_INFO; + + extern "C" + { + __declspec(dllimport) VOID __stdcall GetSystemInfo(SYSTEM_INFO *lpSystemInfo); + __declspec(dllimport) VOID __stdcall GetSystemTime(SYSTEMTIME *lpSystemTime); + __declspec(dllimport) VOID __stdcall GetSystemTimeAsFileTime(FILETIME *lpSystemTimeAsFileTime); + __declspec(dllimport) VOID __stdcall GetLocalTime(SYSTEMTIME *lpSystemTime); + } + + // NOTE: um/timezoneapi.h ////////////////////////////////////////////////////////////////////// + typedef struct _TIME_ZONE_INFORMATION { + LONG Bias; + WCHAR StandardName[32]; + SYSTEMTIME StandardDate; + LONG StandardBias; + WCHAR DaylightName[32]; + SYSTEMTIME DaylightDate; + LONG DaylightBias; + } TIME_ZONE_INFORMATION, *PTIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall FileTimeToSystemTime (const FILETIME* lpFileTime, SYSTEMTIME *lpSystemTime); + __declspec(dllimport) BOOL __stdcall SystemTimeToFileTime (const SYSTEMTIME* lpSystemTime, FILETIME *lpFileTime); + __declspec(dllimport) BOOL __stdcall TzSpecificLocalTimeToSystemTime(const TIME_ZONE_INFORMATION* lpTimeZoneInformation, const SYSTEMTIME* lpLocalTime, const LPSYSTEMTIME lpUniversalTime); + } + + // NOTE: shared/windef.h /////////////////////////////////////////////////////////////////////// + typedef struct tagRECT { + LONG left; + LONG top; + LONG right; + LONG bottom; + } RECT; + + struct HWND__ { + int unused; + }; + typedef struct HWND__ *HWND; + + struct DPI_AWARENESS_CONTEXT__ { + int unused; + }; + typedef struct DPI_AWARENESS_CONTEXT__ *DPI_AWARENESS_CONTEXT; + + typedef enum DPI_AWARENESS { + DPI_AWARENESS_INVALID = -1, + DPI_AWARENESS_UNAWARE = 0, + DPI_AWARENESS_SYSTEM_AWARE = 1, + DPI_AWARENESS_PER_MONITOR_AWARE = 2 + } DPI_AWARENESS; + + #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4) + + // NOTE: um/winuser.h ////////////////////////////////////////////////////////////////////////// + typedef struct tagWINDOWPLACEMENT { + UINT length; + UINT flags; + UINT showCmd; + POINT ptMinPosition; + POINT ptMaxPosition; + RECT rcNormalPosition; + #ifdef _MAC + RECT rcDevice; + #endif + } WINDOWPLACEMENT; + typedef WINDOWPLACEMENT *PWINDOWPLACEMENT, *LPWINDOWPLACEMENT; + + #define SW_HIDE 0 + #define SW_NORMAL 1 + #define SW_MAXIMIZE 3 + #define SW_SHOWNOACTIVATE 4 + #define SW_SHOW 5 + #define SW_FORCEMINIMIZE 11 + + extern "C" + { + __declspec(dllimport) BOOL __stdcall GetWindowRect (HWND hWnd, RECT *lpRect); + __declspec(dllimport) BOOL __stdcall SetWindowPos (HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags); + __declspec(dllimport) UINT __stdcall GetWindowModuleFileNameA(HWND hwnd, LPSTR pszFileName, UINT cchFileNameMax); + __declspec(dllimport) BOOL __stdcall ShowWindow (HWND hWnd, int nCmdShow); + __declspec(dllimport) BOOL __stdcall GetWindowPlacement (HWND hWnd, WINDOWPLACEMENT *lpwndpl); + + } + + // NOTE: um/wininet.h ////////////////////////////////////////////////////////////////////////// + typedef WORD INTERNET_PORT; + typedef VOID *HINTERNET; + + // NOTE: um/winhttp.h ////////////////////////////////////////////////////////////////////////// + #define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY 0 + #define WINHTTP_ACCESS_TYPE_NO_PROXY 1 + #define WINHTTP_ACCESS_TYPE_NAMED_PROXY 3 + #define WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY 4 + + #define INTERNET_DEFAULT_PORT 0 // use the protocol-specific default + #define INTERNET_DEFAULT_HTTP_PORT 80 // " " HTTP " + #define INTERNET_DEFAULT_HTTPS_PORT 443 // " " HTTPS " + + // NOTE: WinHttpOpen + #define WINHTTP_FLAG_ASYNC 0x10000000 // this session is asynchronous (where supported) + #define WINHTTP_FLAG_SECURE_DEFAULTS 0x30000000 // note that this flag also forces async + + // NOTE: WinHttpOpenRequest + #define WINHTTP_FLAG_SECURE 0x00800000 // use SSL if applicable (HTTPS) + #define WINHTTP_FLAG_ESCAPE_PERCENT 0x00000004 // if escaping enabled, escape percent as well + #define WINHTTP_FLAG_NULL_CODEPAGE 0x00000008 // assume all symbols are ASCII, use fast convertion + #define WINHTTP_FLAG_ESCAPE_DISABLE 0x00000040 // disable escaping + #define WINHTTP_FLAG_ESCAPE_DISABLE_QUERY 0x00000080 // if escaping enabled escape path part, but do not escape query + #define WINHTTP_FLAG_BYPASS_PROXY_CACHE 0x00000100 // add "pragma: no-cache" request header + #define WINHTTP_FLAG_REFRESH WINHTTP_FLAG_BYPASS_PROXY_CACHE + #define WINHTTP_FLAG_AUTOMATIC_CHUNKING 0x00000200 // Send request without content-length header or chunked TE + + #define WINHTTP_NO_PROXY_NAME NULL + #define WINHTTP_NO_PROXY_BYPASS NULL + + // + // WINHTTP_QUERY_FLAG_NUMBER - if this bit is set in the dwInfoLevel parameter of + // HttpQueryHeader(), then the value of the header will be converted to a number + // before being returned to the caller, if applicable + // + #define WINHTTP_QUERY_FLAG_NUMBER 0x20000000 + + #define WINHTTP_QUERY_MIME_VERSION 0 + #define WINHTTP_QUERY_CONTENT_TYPE 1 + #define WINHTTP_QUERY_CONTENT_TRANSFER_ENCODING 2 + #define WINHTTP_QUERY_CONTENT_ID 3 + #define WINHTTP_QUERY_CONTENT_DESCRIPTION 4 + #define WINHTTP_QUERY_CONTENT_LENGTH 5 + #define WINHTTP_QUERY_CONTENT_LANGUAGE 6 + #define WINHTTP_QUERY_ALLOW 7 + #define WINHTTP_QUERY_PUBLIC 8 + #define WINHTTP_QUERY_DATE 9 + #define WINHTTP_QUERY_EXPIRES 10 + #define WINHTTP_QUERY_LAST_MODIFIED 11 + #define WINHTTP_QUERY_MESSAGE_ID 12 + #define WINHTTP_QUERY_URI 13 + #define WINHTTP_QUERY_DERIVED_FROM 14 + #define WINHTTP_QUERY_COST 15 + #define WINHTTP_QUERY_LINK 16 + #define WINHTTP_QUERY_PRAGMA 17 + #define WINHTTP_QUERY_VERSION 18 // special: part of status line + #define WINHTTP_QUERY_STATUS_CODE 19 // special: part of status line + #define WINHTTP_QUERY_STATUS_TEXT 20 // special: part of status line + #define WINHTTP_QUERY_RAW_HEADERS 21 // special: all headers as ASCIIZ + #define WINHTTP_QUERY_RAW_HEADERS_CRLF 22 // special: all headers + #define WINHTTP_QUERY_CONNECTION 23 + #define WINHTTP_QUERY_ACCEPT 24 + #define WINHTTP_QUERY_ACCEPT_CHARSET 25 + #define WINHTTP_QUERY_ACCEPT_ENCODING 26 + #define WINHTTP_QUERY_ACCEPT_LANGUAGE 27 + #define WINHTTP_QUERY_AUTHORIZATION 28 + #define WINHTTP_QUERY_CONTENT_ENCODING 29 + #define WINHTTP_QUERY_FORWARDED 30 + #define WINHTTP_QUERY_FROM 31 + #define WINHTTP_QUERY_IF_MODIFIED_SINCE 32 + #define WINHTTP_QUERY_LOCATION 33 + #define WINHTTP_QUERY_ORIG_URI 34 + #define WINHTTP_QUERY_REFERER 35 + #define WINHTTP_QUERY_RETRY_AFTER 36 + #define WINHTTP_QUERY_SERVER 37 + #define WINHTTP_QUERY_TITLE 38 + #define WINHTTP_QUERY_USER_AGENT 39 + #define WINHTTP_QUERY_WWW_AUTHENTICATE 40 + #define WINHTTP_QUERY_PROXY_AUTHENTICATE 41 + #define WINHTTP_QUERY_ACCEPT_RANGES 42 + #define WINHTTP_QUERY_SET_COOKIE 43 + #define WINHTTP_QUERY_COOKIE 44 + #define WINHTTP_QUERY_REQUEST_METHOD 45 // special: GET/POST etc. + #define WINHTTP_QUERY_REFRESH 46 + #define WINHTTP_QUERY_CONTENT_DISPOSITION 47 + + // NOTE: WinHttpQueryHeaders prettifiers for optional parameters. + #define WINHTTP_HEADER_NAME_BY_INDEX NULL + #define WINHTTP_NO_OUTPUT_BUFFER NULL + #define WINHTTP_NO_HEADER_INDEX NULL + + // NOTE: Http Response Status Codes + #define HTTP_STATUS_CONTINUE 100 // OK to continue with request + #define HTTP_STATUS_SWITCH_PROTOCOLS 101 // server has switched protocols in upgrade header + + #define HTTP_STATUS_OK 200 // request completed + #define HTTP_STATUS_CREATED 201 // object created, reason = new URI + #define HTTP_STATUS_ACCEPTED 202 // async completion (TBS) + #define HTTP_STATUS_PARTIAL 203 // partial completion + #define HTTP_STATUS_NO_CONTENT 204 // no info to return + #define HTTP_STATUS_RESET_CONTENT 205 // request completed, but clear form + #define HTTP_STATUS_PARTIAL_CONTENT 206 // partial GET fulfilled + #define HTTP_STATUS_WEBDAV_MULTI_STATUS 207 // WebDAV Multi-Status + + #define HTTP_STATUS_AMBIGUOUS 300 // server couldn't decide what to return + #define HTTP_STATUS_MOVED 301 // object permanently moved + #define HTTP_STATUS_REDIRECT 302 // object temporarily moved + #define HTTP_STATUS_REDIRECT_METHOD 303 // redirection w/ new access method + #define HTTP_STATUS_NOT_MODIFIED 304 // if-modified-since was not modified + #define HTTP_STATUS_USE_PROXY 305 // redirection to proxy, location header specifies proxy to use + #define HTTP_STATUS_REDIRECT_KEEP_VERB 307 // HTTP/1.1: keep same verb + #define HTTP_STATUS_PERMANENT_REDIRECT 308 // Object permanently moved keep verb + + #define HTTP_STATUS_BAD_REQUEST 400 // invalid syntax + #define HTTP_STATUS_DENIED 401 // access denied + #define HTTP_STATUS_PAYMENT_REQ 402 // payment required + #define HTTP_STATUS_FORBIDDEN 403 // request forbidden + #define HTTP_STATUS_NOT_FOUND 404 // object not found + #define HTTP_STATUS_BAD_METHOD 405 // method is not allowed + #define HTTP_STATUS_NONE_ACCEPTABLE 406 // no response acceptable to client found + #define HTTP_STATUS_PROXY_AUTH_REQ 407 // proxy authentication required + #define HTTP_STATUS_REQUEST_TIMEOUT 408 // server timed out waiting for request + #define HTTP_STATUS_CONFLICT 409 // user should resubmit with more info + #define HTTP_STATUS_GONE 410 // the resource is no longer available + #define HTTP_STATUS_LENGTH_REQUIRED 411 // the server refused to accept request w/o a length + #define HTTP_STATUS_PRECOND_FAILED 412 // precondition given in request failed + #define HTTP_STATUS_REQUEST_TOO_LARGE 413 // request entity was too large + #define HTTP_STATUS_URI_TOO_LONG 414 // request URI too long + #define HTTP_STATUS_UNSUPPORTED_MEDIA 415 // unsupported media type + #define HTTP_STATUS_RETRY_WITH 449 // retry after doing the appropriate action. + + #define HTTP_STATUS_SERVER_ERROR 500 // internal server error + #define HTTP_STATUS_NOT_SUPPORTED 501 // required not supported + #define HTTP_STATUS_BAD_GATEWAY 502 // error response received from gateway + #define HTTP_STATUS_SERVICE_UNAVAIL 503 // temporarily overloaded + #define HTTP_STATUS_GATEWAY_TIMEOUT 504 // timed out waiting for gateway + #define HTTP_STATUS_VERSION_NOT_SUP 505 // HTTP version not supported + + #define HTTP_STATUS_FIRST HTTP_STATUS_CONTINUE + #define HTTP_STATUS_LAST HTTP_STATUS_VERSION_NOT_SUP + + #define WINHTTP_CALLBACK_STATUS_RESOLVING_NAME 0x00000001 + #define WINHTTP_CALLBACK_STATUS_NAME_RESOLVED 0x00000002 + #define WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER 0x00000004 + #define WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER 0x00000008 + #define WINHTTP_CALLBACK_STATUS_SENDING_REQUEST 0x00000010 + #define WINHTTP_CALLBACK_STATUS_REQUEST_SENT 0x00000020 + #define WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE 0x00000040 + #define WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED 0x00000080 + #define WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION 0x00000100 + #define WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED 0x00000200 + #define WINHTTP_CALLBACK_STATUS_HANDLE_CREATED 0x00000400 + #define WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING 0x00000800 + #define WINHTTP_CALLBACK_STATUS_DETECTING_PROXY 0x00001000 + #define WINHTTP_CALLBACK_STATUS_REDIRECT 0x00004000 + #define WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE 0x00008000 + #define WINHTTP_CALLBACK_STATUS_SECURE_FAILURE 0x00010000 + #define WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE 0x00020000 + #define WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE 0x00040000 + #define WINHTTP_CALLBACK_STATUS_READ_COMPLETE 0x00080000 + #define WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE 0x00100000 + #define WINHTTP_CALLBACK_STATUS_REQUEST_ERROR 0x00200000 + #define WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE 0x00400000 + + #define WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE 0x01000000 + #define WINHTTP_CALLBACK_STATUS_CLOSE_COMPLETE 0x02000000 + #define WINHTTP_CALLBACK_STATUS_SHUTDOWN_COMPLETE 0x04000000 + #define WINHTTP_CALLBACK_STATUS_SETTINGS_WRITE_COMPLETE 0x10000000 + #define WINHTTP_CALLBACK_STATUS_SETTINGS_READ_COMPLETE 0x20000000 + + #define WINHTTP_CALLBACK_FLAG_RESOLVE_NAME (WINHTTP_CALLBACK_STATUS_RESOLVING_NAME | WINHTTP_CALLBACK_STATUS_NAME_RESOLVED) + #define WINHTTP_CALLBACK_FLAG_CONNECT_TO_SERVER (WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER | WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER) + #define WINHTTP_CALLBACK_FLAG_SEND_REQUEST (WINHTTP_CALLBACK_STATUS_SENDING_REQUEST | WINHTTP_CALLBACK_STATUS_REQUEST_SENT) + #define WINHTTP_CALLBACK_FLAG_RECEIVE_RESPONSE (WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE | WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED) + #define WINHTTP_CALLBACK_FLAG_CLOSE_CONNECTION (WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION | WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED) + #define WINHTTP_CALLBACK_FLAG_HANDLES (WINHTTP_CALLBACK_STATUS_HANDLE_CREATED | WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING) + #define WINHTTP_CALLBACK_FLAG_DETECTING_PROXY WINHTTP_CALLBACK_STATUS_DETECTING_PROXY + #define WINHTTP_CALLBACK_FLAG_REDIRECT WINHTTP_CALLBACK_STATUS_REDIRECT + #define WINHTTP_CALLBACK_FLAG_INTERMEDIATE_RESPONSE WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE + #define WINHTTP_CALLBACK_FLAG_SECURE_FAILURE WINHTTP_CALLBACK_STATUS_SECURE_FAILURE + #define WINHTTP_CALLBACK_FLAG_SENDREQUEST_COMPLETE WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE + #define WINHTTP_CALLBACK_FLAG_HEADERS_AVAILABLE WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE + #define WINHTTP_CALLBACK_FLAG_DATA_AVAILABLE WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE + #define WINHTTP_CALLBACK_FLAG_READ_COMPLETE WINHTTP_CALLBACK_STATUS_READ_COMPLETE + #define WINHTTP_CALLBACK_FLAG_WRITE_COMPLETE WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE + #define WINHTTP_CALLBACK_FLAG_REQUEST_ERROR WINHTTP_CALLBACK_STATUS_REQUEST_ERROR + + #define WINHTTP_CALLBACK_FLAG_GETPROXYFORURL_COMPLETE WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE + + #define WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS (WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE \ + | WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE \ + | WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE \ + | WINHTTP_CALLBACK_STATUS_READ_COMPLETE \ + | WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE \ + | WINHTTP_CALLBACK_STATUS_REQUEST_ERROR \ + | WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE) + + #define WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS 0xffffffff + #define WINHTTP_INVALID_STATUS_CALLBACK ((WINHTTP_STATUS_CALLBACK)(-1L)) + + typedef struct _WINHTTP_EXTENDED_HEADER + { + union + { + CHAR const *pwszName; + WCHAR const *pszName; + }; + union + { + WCHAR const *pwszValue; + CHAR const *pszValue; + }; + } WINHTTP_EXTENDED_HEADER, *PWINHTTP_EXTENDED_HEADER; + + typedef struct _WINHTTP_ASYNC_RESULT + { + DWORD *dwResult; // indicates which async API has encountered an error + DWORD dwError; // the error code if the API failed + } WINHTTP_ASYNC_RESULT, *LPWINHTTP_ASYNC_RESULT, *PWINHTTP_ASYNC_RESULT; + + typedef + VOID + (*WINHTTP_STATUS_CALLBACK)( + HINTERNET hInternet, + DWORD *dwContext, + DWORD dwInternetStatus, + VOID *lpvStatusInformation, + DWORD dwStatusInformationLength + ); + + extern "C" + { + __declspec(dllimport) HINTERNET __stdcall WinHttpOpen(WCHAR const *pszAgentW, DWORD dwAccessType, WCHAR const *pszProxyW, WCHAR const *pszProxyBypassW, DWORD dwFlags); + __declspec(dllimport) BOOL __stdcall WinHttpCloseHandle(HINTERNET hInternet); + __declspec(dllimport) HINTERNET __stdcall WinHttpConnect(HINTERNET hSession, WCHAR const *pswzServerName, INTERNET_PORT nServerPort, DWORD dwReserved); + __declspec(dllimport) BOOL __stdcall WinHttpReadData(HINTERNET hRequest, VOID *lpBuffer, DWORD dwNumberOfBytesToRead, DWORD *lpdwNumberOfBytesRead); + __declspec(dllimport) HINTERNET __stdcall WinHttpOpenRequest(HINTERNET hConnect, WCHAR const *pwszVerb, WCHAR const *pwszObjectName, WCHAR const *pwszVersion, WCHAR const *pwszReferrer, WCHAR const *ppwszAcceptTypes, DWORD dwFlags); + __declspec(dllimport) BOOL __stdcall WinHttpSendRequest(HINTERNET hRequest, WCHAR const *lpszHeaders, DWORD dwHeadersLength, VOID *lpOptional, DWORD dwOptionalLength, DWORD dwTotalLength, DWORD_PTR dwContext); + __declspec(dllimport) DWORD __stdcall WinHttpAddRequestHeadersEx(HINTERNET hRequest, DWORD dwModifiers, ULONGLONG ullFlags, ULONGLONG ullExtra, DWORD cHeaders, WINHTTP_EXTENDED_HEADER *pHeaders); + __declspec(dllimport) BOOL __stdcall WinHttpSetCredentials(HINTERNET hRequest, // HINTERNET handle returned by WinHttpOpenRequest. + DWORD AuthTargets, // Only WINHTTP_AUTH_TARGET_SERVER and WINHTTP_AUTH_TARGET_PROXY are supported in this version and they are mutually exclusive + DWORD AuthScheme, // must be one of the supported Auth Schemes returned from WinHttpQueryAuthSchemes() + WCHAR * pwszUserName, // 1) NULL if default creds is to be used, in which case pszPassword will be ignored + WCHAR * pwszPassword, // 1) "" == Blank Password; 2)Parameter ignored if pszUserName is NULL; 3) Invalid to pass in NULL if pszUserName is not NULL + VOID * pAuthParams); + __declspec(dllimport) BOOL __stdcall WinHttpQueryHeaders(HINTERNET hRequest, DWORD dwInfoLevel, WCHAR const *pwszName, VOID *lpBuffer, DWORD *lpdwBufferLength, DWORD *lpdwIndex); + __declspec(dllimport) BOOL __stdcall WinHttpReceiveResponse(HINTERNET hRequest, VOID *lpReserved); + __declspec(dllimport) WINHTTP_STATUS_CALLBACK __stdcall WinHttpSetStatusCallback(HINTERNET hInternet, WINHTTP_STATUS_CALLBACK lpfnInternetCallback, DWORD dwNotificationFlags, DWORD_PTR dwReserved); + } + + // NOTE: um/DbgHelp.h ////////////////////////////////////////////////////////////////////////// + #define SYMOPT_CASE_INSENSITIVE 0x00000001 + #define SYMOPT_UNDNAME 0x00000002 + #define SYMOPT_DEFERRED_LOADS 0x00000004 + #define SYMOPT_NO_CPP 0x00000008 + #define SYMOPT_LOAD_LINES 0x00000010 + #define SYMOPT_OMAP_FIND_NEAREST 0x00000020 + #define SYMOPT_LOAD_ANYTHING 0x00000040 + #define SYMOPT_IGNORE_CVREC 0x00000080 + #define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 + #define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 + #define SYMOPT_EXACT_SYMBOLS 0x00000400 + #define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 + #define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 + #define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 + #define SYMOPT_PUBLICS_ONLY 0x00004000 + #define SYMOPT_NO_PUBLICS 0x00008000 + #define SYMOPT_AUTO_PUBLICS 0x00010000 + #define SYMOPT_NO_IMAGE_SEARCH 0x00020000 + #define SYMOPT_SECURE 0x00040000 + #define SYMOPT_NO_PROMPTS 0x00080000 + #define SYMOPT_OVERWRITE 0x00100000 + #define SYMOPT_IGNORE_IMAGEDIR 0x00200000 + #define SYMOPT_FLAT_DIRECTORY 0x00400000 + #define SYMOPT_FAVOR_COMPRESSED 0x00800000 + #define SYMOPT_ALLOW_ZERO_ADDRESS 0x01000000 + #define SYMOPT_DISABLE_SYMSRV_AUTODETECT 0x02000000 + #define SYMOPT_READONLY_CACHE 0x04000000 + #define SYMOPT_SYMPATH_LAST 0x08000000 + #define SYMOPT_DISABLE_FAST_SYMBOLS 0x10000000 + #define SYMOPT_DISABLE_SYMSRV_TIMEOUT 0x20000000 + #define SYMOPT_DISABLE_SRVSTAR_ON_STARTUP 0x40000000 + #define SYMOPT_DEBUG 0x80000000 + + #define MAX_SYM_NAME 2000 + + typedef enum { + AddrMode1616, + AddrMode1632, + AddrModeReal, + AddrModeFlat + } ADDRESS_MODE; + + typedef struct _tagADDRESS64 { + DWORD64 Offset; + WORD Segment; + ADDRESS_MODE Mode; + } ADDRESS64, *LPADDRESS64; + + + typedef struct _KDHELP64 { + DWORD64 Thread; + DWORD ThCallbackStack; + DWORD ThCallbackBStore; + DWORD NextCallback; + DWORD FramePointer; + DWORD64 KiCallUserMode; + DWORD64 KeUserCallbackDispatcher; + DWORD64 SystemRangeStart; + DWORD64 KiUserExceptionDispatcher; + DWORD64 StackBase; + DWORD64 StackLimit; + DWORD BuildVersion; + DWORD RetpolineStubFunctionTableSize; + DWORD64 RetpolineStubFunctionTable; + DWORD RetpolineStubOffset; + DWORD RetpolineStubSize; + DWORD64 Reserved0[2]; + } KDHELP64, *PKDHELP64; + + typedef struct _tagSTACKFRAME64 { + ADDRESS64 AddrPC; // program counter + ADDRESS64 AddrReturn; // return address + ADDRESS64 AddrFrame; // frame pointer + ADDRESS64 AddrStack; // stack pointer + ADDRESS64 AddrBStore; // backing store pointer + VOID *FuncTableEntry; // pointer to pdata/fpo or NULL + DWORD64 Params[4]; // possible arguments to the function + BOOL Far; // WOW far call + BOOL Virtual; // is this a virtual frame? + DWORD64 Reserved[3]; + KDHELP64 KdHelp; + } STACKFRAME64; + + typedef struct _IMAGEHLP_LINEW64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) + VOID *Key; // internal + DWORD LineNumber; // line number in file + WCHAR *FileName; // full filename + DWORD64 Address; // first instruction of line + } IMAGEHLP_LINEW64; + + typedef struct _SYMBOL_INFOW { + ULONG SizeOfStruct; + ULONG TypeIndex; // Type Index of symbol + ULONG64 Reserved[2]; + ULONG Index; + ULONG Size; + ULONG64 ModBase; // Base Address of module comtaining this symbol + ULONG Flags; + ULONG64 Value; // Value of symbol, ValuePresent should be 1 + ULONG64 Address; // Address of symbol including base address of module + ULONG Register; // register holding value or pointer to value + ULONG Scope; // scope of the symbol + ULONG Tag; // pdb classification + ULONG NameLen; // Actual length of name + ULONG MaxNameLen; + WCHAR Name[1]; // Name of symbol + } SYMBOL_INFOW; + + typedef BOOL (__stdcall READ_PROCESS_MEMORY_ROUTINE64)(HANDLE hProcess, DWORD64 qwBaseAddress, VOID *lpBuffer, DWORD nSize, DWORD *lpNumberOfBytesRead); + typedef VOID * (__stdcall FUNCTION_TABLE_ACCESS_ROUTINE64)(HANDLE ahProcess, DWORD64 AddrBase); + typedef DWORD64(__stdcall GET_MODULE_BASE_ROUTINE64)(HANDLE hProcess, DWORD64 Address); + typedef DWORD64(__stdcall TRANSLATE_ADDRESS_ROUTINE64)(HANDLE hProcess, HANDLE hThread, ADDRESS64 *lpaddr); + + extern "C" + { + __declspec(dllimport) BOOL __stdcall StackWalk64 (DWORD MachineType, HANDLE hProcess, HANDLE hThread, STACKFRAME64 *StackFrame, VOID *ContextRecord, READ_PROCESS_MEMORY_ROUTINE64 *ReadMemoryRoutine, FUNCTION_TABLE_ACCESS_ROUTINE64 *FunctionTableAccessRoutine, GET_MODULE_BASE_ROUTINE64 *GetModuleBaseRoutine, TRANSLATE_ADDRESS_ROUTINE64 *TranslateAddress); + __declspec(dllimport) BOOL __stdcall SymFromAddrW (HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, SYMBOL_INFOW *Symbol); + __declspec(dllimport) VOID * __stdcall SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase); + __declspec(dllimport) BOOL __stdcall SymGetLineFromAddrW64 (HANDLE hProcess, DWORD64 dwAddr, DWORD *pdwDisplacement, IMAGEHLP_LINEW64 *Line); + __declspec(dllimport) DWORD64 __stdcall SymGetModuleBase64 (HANDLE hProcess, DWORD64 qwAddr); + __declspec(dllimport) BOOL __stdcall SymRefreshModuleList (HANDLE hProcess); + }; + + // NOTE: um/errhandlingapi.h /////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) DWORD __stdcall GetLastError(VOID); + } + + // NOTE: um/libloaderapi.h ///////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) HMODULE __stdcall LoadLibraryA (const CHAR *lpLibFileName); + __declspec(dllimport) BOOL __stdcall FreeLibrary (HMODULE hLibModule); + __declspec(dllimport) void * __stdcall GetProcAddress (HMODULE hModule, const CHAR *lpProcName); + __declspec(dllimport) HMODULE __stdcall GetModuleHandleA (const CHAR *lpModuleName); + __declspec(dllimport) DWORD __stdcall GetModuleFileNameW(HMODULE hModule, WCHAR *lpFilename, DWORD nSize); + } + + // NOTE: um/synchapi.h ///////////////////////////////////////////////////////////////////////// + typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE; + + extern "C" + { + __declspec(dllimport) VOID __stdcall InitializeConditionVariable (CONDITION_VARIABLE *ConditionVariable); + __declspec(dllimport) VOID __stdcall WakeConditionVariable (CONDITION_VARIABLE *ConditionVariable); + __declspec(dllimport) VOID __stdcall WakeAllConditionVariable (CONDITION_VARIABLE *ConditionVariable); + __declspec(dllimport) BOOL __stdcall SleepConditionVariableCS (CONDITION_VARIABLE *ConditionVariable, CRITICAL_SECTION *CriticalSection, DWORD dwMilliseconds); + + __declspec(dllimport) VOID __stdcall InitializeCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) VOID __stdcall EnterCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) VOID __stdcall LeaveCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) BOOL __stdcall InitializeCriticalSectionAndSpinCount(CRITICAL_SECTION *lpCriticalSection, DWORD dwSpinCount); + __declspec(dllimport) BOOL __stdcall InitializeCriticalSectionEx (CRITICAL_SECTION *lpCriticalSection, DWORD dwSpinCount, DWORD Flags); + __declspec(dllimport) DWORD __stdcall SetCriticalSectionSpinCount (CRITICAL_SECTION *lpCriticalSection, DWORD dwSpinCount); + __declspec(dllimport) BOOL __stdcall TryEnterCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) VOID __stdcall DeleteCriticalSection (CRITICAL_SECTION *lpCriticalSection); + + __declspec(dllimport) DWORD __stdcall WaitForSingleObject (HANDLE hHandle, DWORD dwMilliseconds); + __declspec(dllimport) BOOL __stdcall ReleaseSemaphore (HANDLE hSemaphore, LONG lReleaseCount, LONG *lpPreviousCount); + __declspec(dllimport) VOID __stdcall Sleep (DWORD dwMilliseconds); + } + + // NOTE: um/profileapi.h /////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall QueryPerformanceCounter (LARGE_INTEGER* lpPerformanceCount); + __declspec(dllimport) BOOL __stdcall QueryPerformanceFrequency(LARGE_INTEGER* lpFrequency); + } + + // NOTE: um/processthreadsapi.h //////////////////////////////////////////////////////////////// + typedef struct _PROCESS_INFORMATION { + HANDLE hProcess; + HANDLE hThread; + DWORD dwProcessId; + DWORD dwThreadId; + } PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION; + + typedef struct _STARTUPINFOW { + DWORD cb; + WCHAR *lpReserved; + WCHAR *lpDesktop; + WCHAR *lpTitle; + DWORD dwX; + DWORD dwY; + DWORD dwXSize; + DWORD dwYSize; + DWORD dwXCountChars; + DWORD dwYCountChars; + DWORD dwFillAttribute; + DWORD dwFlags; + WORD wShowWindow; + WORD cbReserved2; + BYTE *lpReserved2; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; + } STARTUPINFOW, *LPSTARTUPINFOW; + + typedef DWORD (__stdcall *PTHREAD_START_ROUTINE)( + VOID *lpThreadParameter + ); + typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall CreateProcessW (WCHAR const *lpApplicationName, WCHAR *lpCommandLine, SECURITY_ATTRIBUTES *lpProcessAttributes, SECURITY_ATTRIBUTES *lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, VOID *lpEnvironment, WCHAR const *lpCurrentDirectory, STARTUPINFOW *lpStartupInfo, PROCESS_INFORMATION *lpProcessInformation); + __declspec(dllimport) HANDLE __stdcall CreateThread (SECURITY_ATTRIBUTES *lpThreadAttributes, SIZE_T dwStackSize, PTHREAD_START_ROUTINE lpStartAddress, VOID *lpParameter, DWORD dwCreationFlags, DWORD *lpThreadId); + __declspec(dllimport) DWORD __stdcall GetCurrentThreadId(VOID); + __declspec(dllimport) BOOL __stdcall GetExitCodeProcess(HANDLE hProcess, DWORD *lpExitCode); + __declspec(dllimport) void __stdcall ExitProcess (UINT uExitCode); + } + + // NOTE: um/memoryapi.h //////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) VOID * __stdcall VirtualAlloc (VOID *lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect); + __declspec(dllimport) BOOL __stdcall VirtualProtect(VOID *lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD *lpflOldProtect); + __declspec(dllimport) BOOL __stdcall VirtualFree (VOID *lpAddress, SIZE_T dwSize, DWORD dwFreeType); + } + + // NOTE: shared/bcrypt.h /////////////////////////////////////////////////////////////////////// + typedef VOID *BCRYPT_ALG_HANDLE; + typedef LONG NTSTATUS; + + extern "C" + { + __declspec(dllimport) NTSTATUS __stdcall BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *phAlgorithm, const WCHAR *pszAlgId, const WCHAR *pszImplementation, ULONG dwFlags); + __declspec(dllimport) NTSTATUS __stdcall BCryptGenRandom (BCRYPT_ALG_HANDLE hAlgorithm, UCHAR *pbBuffer, ULONG cbBuffer, ULONG dwFlags); + } + + // NOTE: um/shellapi.h ///////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) HINSTANCE __stdcall ShellExecuteA(HWND hwnd, CHAR const *lpOperation, CHAR const *lpFile, CHAR const *lpParameters, CHAR const *lpDirectory, INT nShowCmd); + __declspec(dllimport) HINSTANCE __stdcall ShellExecuteW(HWND hwnd, WCHAR const *lpOperation, WCHAR const *lpFile, WCHAR const *lpParameters, WCHAR const *lpDirectory, INT nShowCmd); + } + + // NOTE: um/debugapi.h ///////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall IsDebuggerPresent(); + } + + // NOTE: um/namedpipeapi.h ///////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall CreatePipe (HANDLE *hReadPipe, HANDLE *hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize); + __declspec(dllimport) BOOL __stdcall PeekNamedPipe(HANDLE hNamedPipe, VOID *lpBuffer, DWORD nBufferSize, DWORD *lpBytesRead, DWORD *lpTotalBytesAvail, DWORD *lpBytesLeftThisMessage); + } + + // NOTE: um/handleapi.h //////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall SetHandleInformation(HANDLE hObject, DWORD dwMask, DWORD dwFlags); + } + + // NOTE: um/commdlg.h ////////////////////////////////////////////////////////////////////////// + typedef UINT_PTR (__stdcall *LPOFNHOOKPROC)(HWND, UINT, WPARAM, LPARAM); + typedef struct tagOFNW { + DWORD lStructSize; + HWND hwndOwner; + HINSTANCE hInstance; + WCHAR const * lpstrFilter; + LPWSTR lpstrCustomFilter; + DWORD nMaxCustFilter; + DWORD nFilterIndex; + LPWSTR lpstrFile; + DWORD nMaxFile; + LPWSTR lpstrFileTitle; + DWORD nMaxFileTitle; + WCHAR const * lpstrInitialDir; + WCHAR const * lpstrTitle; + DWORD Flags; + WORD nFileOffset; + WORD nFileExtension; + WCHAR const * lpstrDefExt; + LPARAM lCustData; + LPOFNHOOKPROC lpfnHook; + WCHAR const * lpTemplateName; + #ifdef _MAC + LPEDITMENU lpEditInfo; + LPCSTR lpstrPrompt; + #endif + #if (_WIN32_WINNT >= 0x0500) + void * pvReserved; + DWORD dwReserved; + DWORD FlagsEx; + #endif // (_WIN32_WINNT >= 0x0500) + } OPENFILENAMEW, *LPOPENFILENAMEW; + + + #define OFN_READONLY 0x00000001 + #define OFN_OVERWRITEPROMPT 0x00000002 + #define OFN_HIDEREADONLY 0x00000004 + #define OFN_NOCHANGEDIR 0x00000008 + #define OFN_SHOWHELP 0x00000010 + #define OFN_ENABLEHOOK 0x00000020 + #define OFN_ENABLETEMPLATE 0x00000040 + #define OFN_ENABLETEMPLATEHANDLE 0x00000080 + #define OFN_NOVALIDATE 0x00000100 + #define OFN_ALLOWMULTISELECT 0x00000200 + #define OFN_EXTENSIONDIFFERENT 0x00000400 + #define OFN_PATHMUSTEXIST 0x00000800 + #define OFN_FILEMUSTEXIST 0x00001000 + #define OFN_CREATEPROMPT 0x00002000 + #define OFN_SHAREAWARE 0x00004000 + #define OFN_NOREADONLYRETURN 0x00008000 + #define OFN_NOTESTFILECREATE 0x00010000 + #define OFN_NONETWORKBUTTON 0x00020000 + #define OFN_NOLONGNAMES 0x00040000 // force no long names for 4.x modules + #if(WINVER >= 0x0400) + #define OFN_EXPLORER 0x00080000 // new look commdlg + #define OFN_NODEREFERENCELINKS 0x00100000 + #define OFN_LONGNAMES 0x00200000 // force long names for 3.x modules + // OFN_ENABLEINCLUDENOTIFY and OFN_ENABLESIZING require + // Windows 2000 or higher to have any effect. + #define OFN_ENABLEINCLUDENOTIFY 0x00400000 // send include message to callback + #define OFN_ENABLESIZING 0x00800000 + #endif /* WINVER >= 0x0400 */ + #if (_WIN32_WINNT >= 0x0500) + #define OFN_DONTADDTORECENT 0x02000000 + #define OFN_FORCESHOWHIDDEN 0x10000000 // Show All files including System and hidden files + #endif // (_WIN32_WINNT >= 0x0500) + + //FlagsEx Values + #if (_WIN32_WINNT >= 0x0500) + #define OFN_EX_NOPLACESBAR 0x00000001 + #endif // (_WIN32_WINNT >= 0x0500) + + extern "C" + { + __declspec(dllimport) BOOL __stdcall GetSaveFileNameW(LPOPENFILENAMEW); + __declspec(dllimport) BOOL __stdcall GetOpenFileNameW(LPOPENFILENAMEW); + } + + // NOTE: um/shlwapi.h ////////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall PathRelativePathToW(WCHAR *pszPath, WCHAR const *pszFrom, DWORD dwAttrFrom, WCHAR const *pszTo, DWORD dwAttrTo); + __declspec(dllimport) BOOL __stdcall PathIsRelativeW(WCHAR *pszPath); + } + + // NOTE: um/pathcch.h ////////////////////////////////////////////////////////////////////////// + typedef enum PATHCCH_OPTIONS + { + PATHCCH_NONE = 0x0, + + // This option allows applications to gain access to long paths. It has two + // different behaviors. For process configured to enable long paths it will allow + // the returned path to be longer than the max path limit that is normally imposed. + // For process that are not this option will convert long paths into the extended + // length DOS device form (with \\?\ prefix) when the path is longer than the limit. + // This form is not length limited by the Win32 file system API on all versions of Windows. + // This second behavior is the same behavior for OSes that don't have the long path feature. + // This can not be specified with PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH. + PATHCCH_ALLOW_LONG_PATHS = 0x01, + + // Can only be used when PATHCCH_ALLOW_LONG_PATHS is specified. This + // Forces the API to treat the caller as long path enabled, independent of the + // process's long name enabled state. Cannot be used with PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS. + PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS = 0x02, + + // Can only be used when PATHCCH_ALLOW_LONG_PATHS is specified. This + // Forces the API to treat the caller as long path disabled, independent of the + // process's long name enabled state. Cannot be used with PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS. + PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS = 0x04, + + // Disable the normalization of path segments that includes removing trailing dots and spaces. + // This enables access to paths that win32 path normalization will block. + PATHCCH_DO_NOT_NORMALIZE_SEGMENTS = 0x08, + + // Convert the input path into the extended length DOS device path form (with the \\?\ prefix) + // if not already in that form. This enables access to paths that are otherwise not addressable + // due to Win32 normalization rules (that can strip trailing dots and spaces) and path + // length limitations. This option implies the same behavior of PATHCCH_DO_NOT_NORMALIZE_SEGMENTS. + // This can not be specified with PATHCCH_ALLOW_LONG_PATHS. + PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH = 0x10, + + // When combining or normalizing a path ensure there is a trailing backslash. + PATHCCH_ENSURE_TRAILING_SLASH = 0x020, + + // Convert forward slashes to back slashes and collapse multiple slashes. + // This is needed to to support sub-path or identity comparisons. + PATHCCH_CANONICALIZE_SLASHES = 0x040, + } PATHCCH_OPTIONS; + + extern "C" + { + __declspec(dllimport) HRESULT __stdcall PathCchCanonicalizeEx(PWSTR pszPathOut, size_t cchPathOut, WCHAR const *pszPathIn, ULONG dwFlags); + }; + + // NOTE: um/errhandlingapi.h /////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) VOID __stdcall RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const ULONG_PTR* lpArguments); + }; + + // NOTE: include/excpt.h /////////////////////////////////////////////////////////////////// + #define EXCEPTION_EXECUTE_HANDLER 1 + #define EXCEPTION_CONTINUE_SEARCH 0 + #define EXCEPTION_CONTINUE_EXECUTION (-1) + + DN_MSVC_WARNING_POP +#endif // !defined(_INC_WINDOWS) +#endif // !defined(DN_OS_WINDOWS_H) +#endif + +struct DN_W32Error +{ + unsigned long code; + DN_Str8 msg; +}; + +struct DN_W32FolderIteratorW +{ + void *handle; + DN_Str16 file_name; + wchar_t file_name_buf[512]; +}; + +enum DN_W32SyncPrimitiveType +{ + DN_OSW32SyncPrimitiveType_Semaphore, + DN_OSW32SyncPrimitiveType_Mutex, + DN_OSW32SyncPrimitiveType_ConditionVariable, +}; + +struct DN_W32SyncPrimitive +{ + union + { + void *sem; + CRITICAL_SECTION mutex; + CONDITION_VARIABLE cv; + }; + + DN_W32SyncPrimitive *next; +}; + +typedef HRESULT DN_W32SetThreadDescriptionFunc(HANDLE hThread, PWSTR const lpThreadDescription); +struct DN_W32Core +{ + DN_W32SetThreadDescriptionFunc *set_thread_description; + LARGE_INTEGER qpc_frequency; + void *bcrypt_rng_handle; + bool bcrypt_init_success; + bool sym_initialised; + + CRITICAL_SECTION sync_primitive_free_list_mutex; + DN_W32SyncPrimitive *sync_primitive_free_list; +}; + +DN_API void DN_W32_ThreadSetName (DN_Str8 name); + +DN_API DN_Str16 DN_W32_ErrorCodeToMsg16Alloc(DN_U32 error_code); +DN_API DN_W32Error DN_W32_ErrorCodeToMsg (DN_Arena *arena, DN_U32 error_code); +DN_API DN_W32Error DN_W32_ErrorCodeToMsgAlloc (DN_U32 error_code); +DN_API DN_W32Error DN_W32_LastError (DN_Arena *arena); +DN_API DN_W32Error DN_W32_LastErrorAlloc (); +DN_API void DN_W32_MakeProcessDPIAware (); + +// NOTE: Windows Str8 <-> Str16 //////////////////////////////////////////////////////////////////// +DN_API DN_Str16 DN_W32_Str8ToStr16 (DN_Arena *arena, DN_Str8 src); +DN_API int DN_W32_Str8ToStr16Buffer (DN_Str16 src, char *dest, int dest_size); +DN_API DN_Str8 DN_W32_Str16ToStr8 (DN_Arena *arena, DN_Str16 src); +DN_API int DN_W32_Str16ToStr8Buffer (DN_Str16 src, char *dest, int dest_size); +DN_API DN_Str8 DN_W32_Str16ToStr8FromHeap(DN_Str16 src); + +// NOTE: Path navigation /////////////////////////////////////////////////////////////////////////// +DN_API DN_Str16 DN_W32_EXEPathW (DN_Arena *arena); +DN_API DN_Str16 DN_W32_EXEDirW (DN_Arena *arena); +DN_API DN_Str8 DN_W32_WorkingDir (DN_Arena *arena, DN_Str8 suffix); +DN_API DN_Str16 DN_W32_WorkingDirW (DN_Arena *arena, DN_Str16 suffix); +DN_API bool DN_W32_DirWIterate (DN_Str16 path, DN_W32FolderIteratorW *it); +#endif // !defined(DN_OS_WIN32) +#elif defined(DN_PLATFORM_POSIX) || defined(DN_PLATFORM_EMSCRIPTEN) + // DN: Single header generator commented out this header => #include "OS/dn_os_posix.h" +#if !defined(DN_OS_POSIX_H) +#define DN_OS_POSIX_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +#include +#include + +/* +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// $$$$$$\ $$$$$$\ $$$$$$$\ $$$$$$\ $$$$$$\ $$$$$$\ $$\ $$\ +// $$ __$$\ $$ __$$\ $$ __$$\ $$ __$$\ $$ __$$\ \_$$ _|$$ | $$ | +// $$ / $$ |$$ / \__| $$ | $$ |$$ / $$ |$$ / \__| $$ | \$$\ $$ | +// $$ | $$ |\$$$$$$\ $$$$$$$ |$$ | $$ |\$$$$$$\ $$ | \$$$$ / +// $$ | $$ | \____$$\ $$ ____/ $$ | $$ | \____$$\ $$ | $$ $$< +// $$ | $$ |$$\ $$ | $$ | $$ | $$ |$$\ $$ | $$ | $$ /\$$\ +// $$$$$$ |\$$$$$$ | $$ | $$$$$$ |\$$$$$$ |$$$$$$\ $$ / $$ | +// \______/ \______/ \__| \______/ \______/ \______|\__| \__| +// +// dn_os_posix.h +// +//////////////////////////////////////////////////////////////////////////////////////////////////// +*/ + +struct DN_POSIXProcSelfStatus +{ + char name[64]; + DN_U8 name_size; + DN_U32 pid; + DN_U64 vm_peak; + DN_U32 vm_size; +}; + +// NOTE: The POSIX implementation disallows copies of synchronisation objects in +// general hence we have to dynamically allocate these primitives to maintain a +// consistent address. +// +// +// Source: The Open Group Base Specifications Issue 7, 2018 edition +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_09 +// +// 2.9.9 Synchronization Object Copies and Alternative Mappings +// +// For barriers, condition variables, mutexes, and read-write locks, [TSH] +// [Option Start] if the process-shared attribute is set to +// PTHREAD_PROCESS_PRIVATE, [Option End] only the synchronization object at the +// address used to initialize it can be used for performing synchronization. The +// effect of referring to another mapping of the same object when locking, +// unlocking, or destroying the object is undefined. [...] The effect of +// referring to a copy of the object when locking, unlocking, or destroying it +// is undefined. + +enum DN_POSIXSyncPrimitiveType +{ + DN_OSPOSIXSyncPrimitiveType_Semaphore, + DN_OSPOSIXSyncPrimitiveType_Mutex, + DN_OSPOSIXSyncPrimitiveType_ConditionVariable, +}; + +struct DN_POSIXSyncPrimitive +{ + union + { + sem_t sem; + pthread_mutex_t mutex; + pthread_cond_t cv; + }; + DN_POSIXSyncPrimitive *next; +}; + +struct DN_POSIXCore +{ + DN_POSIXSyncPrimitive *sync_primitive_free_list; + pthread_mutex_t sync_primitive_free_list_mutex; + bool clock_monotonic_raw; +}; + +DN_API void DN_Posix_Init(DN_POSIXCore *posix); +DN_API void DN_Posix_ThreadSetName(DN_Str8 name); +DN_API DN_POSIXProcSelfStatus DN_Posix_ProcSelfStatus(); +#endif // !defined(DN_OS_POSIX_H) +#else + #error Please define a platform e.g. 'DN_PLATFORM_WIN32' to enable the correct implementation for platform APIs +#endif + +// DN: Single header generator commented out this header => #include "OS/dn_os_tls.h" +#if !defined(DN_OS_TLS_H) +#define DN_OS_TLS_H + +#if defined(_CLANGD) + // 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" +#endif + +// NOTE: DN_OSErrSink +enum DN_OSErrSinkMode +{ + DN_OSErrSinkMode_Nil, // Default behaviour to accumulate errors into the sink + DN_OSErrSinkMode_DebugBreakOnEndAndLog, // Debug break (int3) when error is encountered and the sink is ended by the 'end and log' functions. + DN_OSErrSinkMode_ExitOnError, // When an error is encountered, exit the program with the error code of the error that was caught. +}; + +struct DN_OSErrSinkMsg +{ + DN_I32 error_code; + DN_Str8 msg; + DN_CallSite call_site; + DN_OSErrSinkMsg *next; + DN_OSErrSinkMsg *prev; +}; + +struct DN_OSErrSinkNode +{ + DN_CallSite call_site; // Call site that the node was created + DN_OSErrSinkMode mode; // Controls how the sink behaves when an error is registered onto the sink. + DN_OSErrSinkMsg *msg_sentinel; // List of error messages accumulated for the current scope + DN_U64 arena_pos; // Position to reset the arena when the scope is ended +}; + +struct DN_OSErrSink +{ + DN_Arena * arena; // Dedicated allocator from the thread's local storage + DN_OSErrSinkNode stack[128]; // Each entry contains errors accumulated between a [begin, end] region of the active sink. + DN_USize stack_size; +}; + +enum DN_OSTLSArena +{ + DN_OSTLSArena_Main, // NOTE: Arena for permanent allocations + DN_OSTLSArena_ErrorSink, // NOTE: Arena for logging error information for this thread + + // NOTE: Per-thread scratch arenas (2 to prevent aliasing) + DN_OSTLSArena_TMem0, + DN_OSTLSArena_TMem1, + + DN_OSTLSArena_Count, +}; + +struct DN_OSTLS +{ + DN_B32 init; // Flag to track if TLS has been initialised + DN_U64 thread_id; + DN_CallSite call_site; // Stores call-site information when requested by thread + DN_OSErrSink err_sink; // Error handling state + DN_Arena arenas[DN_OSTLSArena_Count]; // Default arenas that the thread has access to implicitly + DN_Arena * arena_stack[8]; // Active stack of arenas push/popped arenas on into the TLS + DN_USize arena_stack_index; + + DN_Arena * frame_arena; + char name[64]; + DN_U8 name_size; +}; + +// Push the temporary memory arena when retrieved, popped when the arena goes +// out of scope. Pushed arenas are used automatically as the allocator in TLS +// suffixed function. +enum DN_OSTLSPushTMem +{ + DN_OSTLSPushTMem_No, + DN_OSTLSPushTMem_Yes, +}; + +struct DN_OSTLSTMem +{ + DN_OSTLSTMem(DN_OSTLS *context, uint8_t context_index, DN_OSTLSPushTMem push_scratch); + ~DN_OSTLSTMem(); + DN_Arena *arena; + DN_B32 destructed; + DN_OSTLSPushTMem push_arena; + DN_ArenaTempMem temp_mem; +}; + +struct DN_OSTLSInitArgs +{ + DN_U64 reserve; + DN_U64 commit; + DN_U64 err_sink_reserve; + DN_U64 err_sink_commit; +}; + +DN_API void DN_OS_TLSInit (DN_OSTLS *tls, DN_OSTLSInitArgs args); +DN_API void DN_OS_TLSDeinit (DN_OSTLS *tls); +DN_API DN_OSTLS * DN_OS_TLSGet (); +DN_API void DN_OS_TLSSetCurrentThreadTLS (DN_OSTLS *tls); +DN_API DN_Arena * DN_OS_TLSArena (); +DN_API DN_OSTLSTMem DN_OS_TLSGetTMem (void const *conflict_arena, DN_OSTLSPushTMem push_tmp_mem); +DN_API void DN_OS_TLSPushArena (DN_Arena *arena); +DN_API void DN_OS_TLSPopArena (); +DN_API DN_Arena * DN_OS_TLSTopArena (); +DN_API void DN_OS_TLSBeginFrame (DN_Arena *frame_arena); +DN_API DN_Arena * DN_OS_TLSFrameArena (); +#define DN_OS_TLSSaveCallSite do { DN_OS_TLSGet()->call_site = DN_CALL_SITE; } while (0) +#define DN_OS_TLSTMem(...) DN_OS_TLSGetTMem(__VA_ARGS__, DN_OSTLSPushTMem_No) +#define DN_OS_TLSPushTMem(...) DN_OS_TLSGetTMem(__VA_ARGS__, DN_OSTLSPushTMem_Yes) + +DN_API DN_OSErrSink * DN_OS_ErrSinkBegin_ (DN_OSErrSinkMode mode, DN_CallSite call_site); +#define DN_OS_ErrSinkBegin(mode) DN_OS_ErrSinkBegin_(mode, DN_CALL_SITE) +#define DN_OS_ErrSinkBeginDefault() DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil) +DN_API bool DN_OS_ErrSinkHasError (DN_OSErrSink *err); +DN_API DN_OSErrSinkMsg * DN_OS_ErrSinkEnd (DN_Arena *arena, DN_OSErrSink *err); +DN_API DN_Str8 DN_OS_ErrSinkEndStr8 (DN_Arena *arena, DN_OSErrSink *err); +DN_API void DN_OS_ErrSinkEndAndIgnore (DN_OSErrSink *err); +DN_API bool DN_OS_ErrSinkEndAndLogError_ (DN_OSErrSink *err, DN_CallSite call_site, DN_Str8 msg); +DN_API bool DN_OS_ErrSinkEndAndLogErrorFV_ (DN_OSErrSink *err, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API bool DN_OS_ErrSinkEndAndLogErrorF_ (DN_OSErrSink *err, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, ...); +DN_API void DN_OS_ErrSinkEndAndExitIfErrorF_ (DN_OSErrSink *err, DN_CallSite call_site, DN_U32 exit_val, DN_FMT_ATTRIB char const *fmt, ...); +DN_API void DN_OS_ErrSinkEndAndExitIfErrorFV_ (DN_OSErrSink *err, DN_CallSite call_site, DN_U32 exit_val, DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API void DN_OS_ErrSinkAppendFV_ (DN_OSErrSink *err, DN_U32 error_code, DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API void DN_OS_ErrSinkAppendF_ (DN_OSErrSink *err, DN_U32 error_code, DN_FMT_ATTRIB char const *fmt, ...); +#define DN_OS_ErrSinkEndAndLogError(err, err_msg) DN_OS_ErrSinkEndAndLogError_(err, DN_CALL_SITE, err_msg) +#define DN_OS_ErrSinkEndAndLogErrorFV(err, fmt, args) DN_OS_ErrSinkEndAndLogErrorFV_(err, DN_CALL_SITE, fmt, args) +#define DN_OS_ErrSinkEndAndLogErrorF(err, fmt, ...) DN_OS_ErrSinkEndAndLogErrorF_(err, DN_CALL_SITE, fmt, ##__VA_ARGS__) +#define DN_OS_ErrSinkEndAndExitIfErrorFV(err, exit_val, fmt, args) DN_OS_ErrSinkEndAndExitIfErrorFV_(err, DN_CALL_SITE, exit_val, fmt, args) +#define DN_OS_ErrSinkEndAndExitIfErrorF(err, exit_val, fmt, ...) DN_OS_ErrSinkEndAndExitIfErrorF_(err, DN_CALL_SITE, exit_val, fmt, ##__VA_ARGS__) + +#define DN_OS_ErrSinkAppendFV(error, error_code, fmt, args) \ + do { \ + DN_OS_TLSSaveCallSite; \ + DN_OS_ErrSinkAppendFV_(error, error_code, fmt, args); \ + } while (0) + +#define DN_OS_ErrSinkAppendF(error, error_code, fmt, ...) \ + do { \ + DN_OS_TLSSaveCallSite; \ + DN_OS_ErrSinkAppendF_(error, error_code, fmt, ##__VA_ARGS__); \ + } while (0) + +#endif // defined(DN_OS_TLS_H) +// DN: Single header generator commented out this header => #include "OS/dn_os.h" +#if !defined(DN_OS_H) +#define DN_OS_H + +#if defined(_CLANGD) + // 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" +#endif + +#include // operator new + +#if !defined(DN_OS_WIN32) || defined(DN_OS_WIN32_USE_PTHREADS) + #include + #include +#endif + +#if defined(DN_PLATFORM_POSIX) || defined(DN_PLATFORM_EMSCRIPTEN) + #include // errno + #include // O_RDONLY ... etc + #include // ioctl + #include // mmap + #include // getrandom + #include // stat + #include // pid_t + #include // waitpid + #include // clock_gettime, nanosleep + #include // access, gettid, write + + #if !defined(DN_PLATFORM_EMSCRIPTEN) + #include // FICLONE + #include // sendfile + #endif +#endif + +#if defined(DN_PLATFORM_EMSCRIPTEN) + #include // emscripten_fetch (for DN_OSHttpResponse) +#endif + +extern DN_CPUFeatureDecl g_dn_cpu_feature_decl[DN_CPUFeature_Count]; + +// NOTE: DN_OSDate ///////////////////////////////////////////////////////////////////////////////// +struct DN_OSDateTimeStr8 +{ + char date[DN_ArrayCountU("YYYY-MM-SS")]; + DN_U8 date_size; + char hms[DN_ArrayCountU("HH:MM:SS")]; + DN_U8 hms_size; +}; + +struct DN_OSDateTime +{ + DN_U8 day; + DN_U8 month; + DN_U16 year; + DN_U8 hour; + DN_U8 minutes; + DN_U8 seconds; +}; + +struct DN_OSTimer /// Record time between two time-points using the OS's performance counter. +{ + DN_U64 start; + DN_U64 end; +}; + +#if !defined(DN_NO_OS_FILE_API) +// NOTE: DN_OSFile ///////////////////////////////////////////////////////////////////////////////// +enum DN_OSPathInfoType +{ + DN_OSPathInfoType_Unknown, + DN_OSPathInfoType_Directory, + DN_OSPathInfoType_File, +}; + +struct DN_OSPathInfo +{ + bool exists; + DN_OSPathInfoType type; + DN_U64 create_time_in_s; + DN_U64 last_write_time_in_s; + DN_U64 last_access_time_in_s; + DN_U64 size; +}; + +struct DN_OSDirIterator +{ + void *handle; + DN_Str8 file_name; + char buffer[512]; +}; + +// NOTE: R/W Stream API //////////////////////////////////////////////////////////////////////////// +struct DN_OSFileRead +{ + bool success; + DN_USize bytes_read; +}; + +struct DN_OSFile +{ + bool error; + void *handle; +}; + +enum DN_OSFileOpen +{ + DN_OSFileOpen_CreateAlways, // Create file if it does not exist, otherwise, zero out the file and open + DN_OSFileOpen_OpenIfExist, // Open file at path only if it exists + DN_OSFileOpen_OpenAlways, // Open file at path, create file if it does not exist +}; + +typedef DN_U32 DN_OSFileAccess; + +enum DN_OSFileAccess_ +{ + DN_OSFileAccess_Read = 1 << 0, + DN_OSFileAccess_Write = 1 << 1, + DN_OSFileAccess_Execute = 1 << 2, + DN_OSFileAccess_AppendOnly = 1 << 3, // This flag cannot be combined with any other access mode + DN_OSFileAccess_ReadWrite = DN_OSFileAccess_Read | DN_OSFileAccess_Write, + DN_OSFileAccess_All = DN_OSFileAccess_ReadWrite | DN_OSFileAccess_Execute | DN_OSFileAccess_AppendOnly, +}; +#endif // DN_NO_OS_FILE_API + +// NOTE: DN_OSPath //////////////////////////////////////////////////////////////////////////////// +#if !defined(DN_OSPathSeperator) + #if defined(DN_OS_WIN32) + #define DN_OSPathSeperator "\\" + #else + #define DN_OSPathSeperator "/" + #endif + #define DN_OSPathSeperatorString DN_Str8Lit(DN_OSPathSeperator) +#endif + +struct DN_OSPathLink +{ + DN_Str8 string; + DN_OSPathLink *next; + DN_OSPathLink *prev; +}; + +struct DN_OSPath +{ + bool has_prefix_path_separator; + DN_OSPathLink *head; + DN_OSPathLink *tail; + DN_USize string_size; + DN_U16 links_size; +}; + +// NOTE: DN_OSExec ///////////////////////////////////////////////////////////////////////////////// +typedef DN_U32 DN_OSExecFlags; + +enum DN_OSExecFlags_ +{ + DN_OSExecFlags_Nil = 0, + DN_OSExecFlags_SaveStdout = 1 << 0, + DN_OSExecFlags_SaveStderr = 1 << 1, + DN_OSExecFlags_SaveOutput = DN_OSExecFlags_SaveStdout | DN_OSExecFlags_SaveStderr, + DN_OSExecFlags_MergeStderrToStdout = 1 << 2 | DN_OSExecFlags_SaveOutput, +}; + +struct DN_OSExecAsyncHandle +{ + DN_OSExecFlags exec_flags; + DN_U32 os_error_code; + DN_U32 exit_code; + void *process; + void *stdout_read; + void *stdout_write; + void *stderr_read; + void *stderr_write; +}; + +struct DN_OSExecResult +{ + bool finished; + DN_Str8 stdout_text; + DN_Str8 stderr_text; + DN_U32 os_error_code; + DN_U32 exit_code; +}; + +struct DN_OSExecArgs +{ + DN_OSExecFlags flags; + DN_Str8 working_dir; + DN_Slice environment; +}; + +// NOTE: DN_OSSemaphore //////////////////////////////////////////////////////////////////////////// +DN_U32 const DN_OS_SEMAPHORE_INFINITE_TIMEOUT = UINT32_MAX; + +struct DN_OSSemaphore +{ + DN_U64 handle; +}; + +enum DN_OSSemaphoreWaitResult +{ + DN_OSSemaphoreWaitResult_Failed, + DN_OSSemaphoreWaitResult_Success, + DN_OSSemaphoreWaitResult_Timeout, +}; + +struct DN_OSMutex +{ + DN_U64 handle; +}; + +struct DN_OSConditionVariable +{ + DN_U64 handle; +}; + +// NOTE: DN_OSThread +typedef DN_I32(DN_OSThreadFunc)(struct DN_OSThread *); + +struct DN_OSThread +{ + DN_Str8x64 name; + DN_OSTLS tls; + DN_OSTLSInitArgs tls_init_args; + void *handle; + DN_U64 thread_id; + void *user_context; + DN_OSThreadFunc *func; + DN_OSSemaphore init_semaphore; +}; + +// NOTE: DN_OSHttp +enum DN_OSHttpRequestSecure +{ + DN_OSHttpRequestSecure_No, + DN_OSHttpRequestSecure_Yes, +}; + +struct DN_OSHttpResponse +{ + // NOTE: Response data + DN_U32 error_code; + DN_Str8 error_msg; + DN_U16 http_status; + DN_Str8 body; + DN_B32 done; + + // NOTE: Book-keeping + DN_Arena *arena; // Allocates memory for the response + + // NOTE: Async book-keeping + // Synchronous HTTP response uses the TLS scratch arena whereas async + // calls use their own dedicated arena. + DN_Arena tmp_arena; + DN_Arena *tmem_arena; + DN_Str8Builder builder; + DN_OSSemaphore on_complete_semaphore; + + #if defined(DN_PLATFORM_EMSCRIPTEN) + emscripten_fetch_t *em_handle; + #elif defined(DN_PLATFORM_WIN32) + HINTERNET w32_request_session; + HINTERNET w32_request_connection; + HINTERNET w32_request_handle; #endif }; +struct DN_OSCore +{ + DN_CPUReport cpu_report; + DN_OSTLS tls; // Thread local storage state for the main thread. + + // NOTE: Logging + DN_LOGEmitFromTypeFVFunc * log_callback; // Set this pointer to override the logging routine + void * log_user_data; // User pointer passed into 'log_callback' + bool log_to_file; // Output logs to file as well as standard out + DN_OSFile log_file; // TODO(dn): Hmmm, how should we do this... ? + DN_TicketMutex log_file_mutex; // Is locked when instantiating the log_file for the first time + bool log_no_colour; // Disable colours in the logging output + + // NOTE: OS + DN_U32 logical_processor_count; + DN_U32 page_size; + DN_U32 alloc_granularity; + + // NOTE: Memory + // Total OS mem allocs in lifetime of program (e.g. malloc, VirtualAlloc, HeapAlloc ...). This + // only includes allocations routed through the library such as the growing nature of arenas or + // using the memory allocation routines in the library like DN_OS_MemCommit and so forth. + DN_U64 vmem_allocs_total; + DN_U64 vmem_allocs_frame; // Total OS virtual memory allocs since the last 'DN_Core_FrameBegin' was invoked + DN_U64 mem_allocs_total; + DN_U64 mem_allocs_frame; // Total OS heap allocs since the last 'DN_Core_FrameBegin' was invoked + + DN_Arena arena; + void *platform_context; +}; + +struct DN_OSDiskSpace +{ + bool success; + DN_U64 avail; + DN_U64 size; +}; + +DN_API void DN_OS_EmitLogsWithOSPrintFunctions (DN_OSCore *os); +DN_API void DN_OS_DumpThreadContextArenaStat (DN_Str8 file_path); + +DN_API DN_Str8 DN_OS_BytesFromHexPtrArenaFrame (void const *hex, DN_USize hex_count); +DN_API DN_Str8 DN_OS_BytesFromHexStr8ArenaFrame (DN_Str8 hex); +DN_API DN_Str8 DN_OS_HexFromBytesPtrArenaFrame (void const *bytes, DN_USize bytes_count); +DN_API DN_Str8 DN_OS_HexFromBytesPtrArenaTLS (void const *bytes, DN_USize bytes_count); + +DN_API void * DN_OS_MemReserve (DN_USize size, DN_MemCommit commit, DN_MemPage page_flags); +DN_API bool DN_OS_MemCommit (void *ptr, DN_USize size, DN_U32 page_flags); +DN_API void DN_OS_MemDecommit (void *ptr, DN_USize size); +DN_API void DN_OS_MemRelease (void *ptr, DN_USize size); +DN_API int DN_OS_MemProtect (void *ptr, DN_USize size, DN_U32 page_flags); + +DN_API void * DN_OS_MemAlloc (DN_USize size, DN_ZMem z_mem); +DN_API void DN_OS_MemDealloc (void *ptr); + +DN_API DN_OSDateTime DN_OS_DateLocalTimeNow (); +DN_API DN_OSDateTimeStr8 DN_OS_DateLocalTimeStr8Now (char date_separator = '-', char hms_separator = ':'); +DN_API DN_OSDateTimeStr8 DN_OS_DateLocalTimeStr8 (DN_OSDateTime time, char date_separator = '-', char hms_separator = ':'); +DN_API DN_U64 DN_OS_DateUnixTimeNs (); +#define DN_OS_DateUnixTimeUs() (DN_OS_DateUnixTimeNs() / 1000) +#define DN_OS_DateUnixTimeMs() (DN_OS_DateUnixTimeNs() / (1000 * 1000)) +#define DN_OS_DateUnixTimeS() (DN_OS_DateUnixTimeNs() / (1000 * 1000 * 1000)) +DN_API DN_OSDateTime DN_OS_DateUnixTimeSToDate (DN_U64 time); +DN_API DN_U64 DN_OS_DateLocalToUnixTimeS (DN_OSDateTime date); +DN_API DN_U64 DN_OS_DateToUnixTimeS (DN_OSDateTime date); +DN_API bool DN_OS_DateIsValid (DN_OSDateTime date); + +DN_API void DN_OS_GenBytesSecure (void *buffer, DN_U32 size); +DN_API bool DN_OS_SetEnvVar (DN_Str8 name, DN_Str8 value); +DN_API DN_OSDiskSpace DN_OS_DiskSpace (DN_Str8 path); +DN_API DN_Str8 DN_OS_EXEPath (DN_Arena *arena); +DN_API DN_Str8 DN_OS_EXEDir (DN_Arena *arena); +#define DN_OS_EXEDirFromTLS() DN_OS_EXEDir(DN_OS_TLSTopArena()) +DN_API void DN_OS_SleepMs (DN_UInt milliseconds); + +DN_API DN_U64 DN_OS_PerfCounterNow (); +DN_API DN_U64 DN_OS_PerfCounterFrequency (); +DN_API DN_F64 DN_OS_PerfCounterS (DN_U64 begin, uint64_t end); +DN_API DN_F64 DN_OS_PerfCounterMs (DN_U64 begin, uint64_t end); +DN_API DN_F64 DN_OS_PerfCounterUs (DN_U64 begin, uint64_t end); +DN_API DN_F64 DN_OS_PerfCounterNs (DN_U64 begin, uint64_t end); +DN_API DN_OSTimer DN_OS_TimerBegin (); +DN_API void DN_OS_TimerEnd (DN_OSTimer *timer); +DN_API DN_F64 DN_OS_TimerS (DN_OSTimer timer); +DN_API DN_F64 DN_OS_TimerMs (DN_OSTimer timer); +DN_API DN_F64 DN_OS_TimerUs (DN_OSTimer timer); +DN_API DN_F64 DN_OS_TimerNs (DN_OSTimer timer); +DN_API DN_U64 DN_OS_EstimateTSCPerSecond (uint64_t duration_ms_to_gauge_tsc_frequency); + +DN_API bool DN_OS_FileCopy (DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *err); +DN_API bool DN_OS_FileMove (DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *err); + +DN_API DN_OSFile DN_OS_FileOpen (DN_Str8 path, DN_OSFileOpen open_mode, DN_OSFileAccess access, DN_OSErrSink *err); +DN_API DN_OSFileRead DN_OS_FileRead (DN_OSFile *file, void *buffer, DN_USize size, DN_OSErrSink *err); +DN_API bool DN_OS_FileWritePtr (DN_OSFile *file, void const *data, DN_USize size, DN_OSErrSink *err); +DN_API bool DN_OS_FileWrite (DN_OSFile *file, DN_Str8 buffer, DN_OSErrSink *err); +DN_API bool DN_OS_FileWriteFV (DN_OSFile *file, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API bool DN_OS_FileWriteF (DN_OSFile *file, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, ...); +DN_API bool DN_OS_FileFlush (DN_OSFile *file, DN_OSErrSink *err); +DN_API void DN_OS_FileClose (DN_OSFile *file); + +DN_API DN_Str8 DN_OS_FileReadAll (DN_Allocator alloc_type, void *allocator, DN_Str8 path, DN_OSErrSink *err); +DN_API DN_Str8 DN_OS_FileReadAllArena (DN_Arena *arena, DN_Str8 path, DN_OSErrSink *err); +DN_API DN_Str8 DN_OS_FileReadAllPool (DN_Pool *pool, DN_Str8 path, DN_OSErrSink *err); +DN_API DN_Str8 DN_OS_FileReadAllTLS (DN_Str8 path, DN_OSErrSink *err); +DN_API bool DN_OS_FileWriteAll (DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *err); +DN_API bool DN_OS_FileWriteAllFV (DN_Str8 path, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API bool DN_OS_FileWriteAllF (DN_Str8 path, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, ...); +DN_API bool DN_OS_FileWriteAllSafe (DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *err); +DN_API bool DN_OS_FileWriteAllSafeFV (DN_Str8 path, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API bool DN_OS_FileWriteAllSafeF (DN_Str8 path, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, ...); + +DN_API DN_OSPathInfo DN_OS_PathInfo (DN_Str8 path); +DN_API bool DN_OS_PathIsOlderThan (DN_Str8 file, DN_Str8 check_against); +DN_API bool DN_OS_PathDelete (DN_Str8 path); +DN_API bool DN_OS_PathIsFile (DN_Str8 path); +DN_API bool DN_OS_PathIsDir (DN_Str8 path); +DN_API bool DN_OS_PathMakeDir (DN_Str8 path); +DN_API bool DN_OS_PathIterateDir (DN_Str8 path, DN_OSDirIterator *it); + +DN_API bool DN_OS_PathAddRef (DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path); +DN_API bool DN_OS_PathAddRefTLS (DN_OSPath *fs_path, DN_Str8 path); +DN_API bool DN_OS_PathAddRefFrame (DN_OSPath *fs_path, DN_Str8 path); +DN_API bool DN_OS_PathAdd (DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path); +#define DN_OS_PathAddFromTLS(...) DN_OS_PathAdd(DN_OS_TLSTopArena(), ##__VA_ARGS__) +#define DN_OS_PathAddFromFrame(...) DN_OS_PathAdd(DN_OS_TLSFrameArena(), ##__VA_ARGS__) +DN_API bool DN_OS_PathAddF (DN_Arena *arena, DN_OSPath *fs_path, DN_FMT_ATTRIB char const *fmt, ...); +#define DN_OS_PathAddFFromTLS(...) DN_OS_PathAddF(DN_OS_TLSTopArena(), ##__VA_ARGS__) +#define DN_OS_PathAddFFromFrame(...) DN_OS_PathAddF(DN_OS_TLSFrameArena(), ##__VA_ARGS__) +DN_API bool DN_OS_PathPop (DN_OSPath *fs_path); +DN_API DN_Str8 DN_OS_PathBuildWithSeparator (DN_Arena *arena, DN_OSPath const *fs_path, DN_Str8 path_separator); +#define DN_OS_PathBuildWithSeperatorFromTLS(...) DN_OS_PathBuildWithSeperator(DN_OS_TLSTopArena(), ##__VA_ARGS__) +#define DN_OS_PathBuildWithSeperatorFromFrame(...) DN_OS_PathBuildWithSeperator(DN_OS_TLSFrameArena(), ##__VA_ARGS__) +DN_API DN_Str8 DN_OS_PathTo (DN_Arena *arena, DN_Str8 path, DN_Str8 path_separtor); +#define DN_OS_PathToFromTLS(...) DN_OS_PathTo(DN_OS_TLSTopArena(), ##__VA_ARGS__) +#define DN_OS_PathToFromFrame(...) DN_OS_PathTo(DN_OS_TLSFrameArena(), ##__VA_ARGS__) +DN_API DN_Str8 DN_OS_PathToF (DN_Arena *arena, DN_Str8 path_separator, DN_FMT_ATTRIB char const *fmt, ...); +#define DN_OS_PathToFFromTLS(...) DN_OS_PathToF(DN_OS_TLSTopArena(), ##__VA_ARGS__) +#define DN_OS_PathToFFromFrame(...) DN_OS_PathToF(DN_OS_TLSFrameArena(), ##__VA_ARGS__) +DN_API DN_Str8 DN_OS_Path (DN_Arena *arena, DN_Str8 path); +#define DN_OS_PathFromTLS(...) DN_OS_Path(DN_OS_TLSTopArena(), ##__VA_ARGS__) +#define DN_OS_PathFromFrame(...) DN_OS_Path(DN_OS_TLSFrameArena(), ##__VA_ARGS__) +DN_API DN_Str8 DN_OS_PathF (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...); +#define DN_OS_PathFFromTLS(...) DN_OS_PathF(DN_OS_TLSTopArena(), ##__VA_ARGS__) +#define DN_OS_PathFFromFrame(...) DN_OS_PathF(DN_OS_TLSFrameArena(), ##__VA_ARGS__) + +#define DN_OS_PathBuildFwdSlash(allocator, fs_path) DN_OS_PathBuildWithSeparator(allocator, fs_path, DN_Str8Lit("/")) +#define DN_OS_PathBuildBackSlash(allocator, fs_path) DN_OS_PathBuildWithSeparator(allocator, fs_path, DN_Str8Lit("\\")) +#define DN_OS_PathBuild(allocator, fs_path) DN_OS_PathBuildWithSeparator(allocator, fs_path, DN_OSPathSeparatorString) + +DN_API void DN_OS_Exit (int32_t exit_code); +DN_API DN_OSExecResult DN_OS_ExecPump (DN_OSExecAsyncHandle handle, char *stdout_buffer, size_t *stdout_size, char *stderr_buffer, size_t *stderr_size, DN_U32 timeout_ms, DN_OSErrSink *err); +DN_API DN_OSExecResult DN_OS_ExecWait (DN_OSExecAsyncHandle handle, DN_Arena *arena, DN_OSErrSink *err); +DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync (DN_Slice cmd_line, DN_OSExecArgs *args, DN_OSErrSink *err); +DN_API DN_OSExecResult DN_OS_Exec (DN_Slice cmd_line, DN_OSExecArgs *args, DN_Arena *arena, DN_OSErrSink *err); +DN_API DN_OSExecResult DN_OS_ExecOrAbort (DN_Slice cmd_line, DN_OSExecArgs *args, DN_Arena *arena); +#define DN_OS_ExecOrAbortFromTLS (...) DN_OS_ExecOrAbort(__VA_ARGS__, DN_OS_TLSTopArena()) + +DN_API DN_OSSemaphore DN_OS_SemaphoreInit (DN_U32 initial_count); +DN_API bool DN_OS_SemaphoreIsValid (DN_OSSemaphore *semaphore); +DN_API void DN_OS_SemaphoreDeinit (DN_OSSemaphore *semaphore); +DN_API void DN_OS_SemaphoreIncrement (DN_OSSemaphore *semaphore, DN_U32 amount); +DN_API DN_OSSemaphoreWaitResult DN_OS_SemaphoreWait (DN_OSSemaphore *semaphore, DN_U32 timeout_ms); + +DN_API DN_OSMutex DN_OS_MutexInit (); +DN_API void DN_OS_MutexDeinit (DN_OSMutex *mutex); +DN_API void DN_OS_MutexLock (DN_OSMutex *mutex); +DN_API void DN_OS_MutexUnlock (DN_OSMutex *mutex); +#define DN_OS_MutexScope(mutex) DN_DeferLoop(DN_OS_MutexLock(mutex), DN_OS_MutexUnlock(mutex)) + +DN_API DN_OSConditionVariable DN_OS_ConditionVariableInit (); +DN_API void DN_OS_ConditionVariableDeinit (DN_OSConditionVariable *cv); +DN_API bool DN_OS_ConditionVariableWait (DN_OSConditionVariable *cv, DN_OSMutex *mutex, DN_U64 sleep_ms); +DN_API bool DN_OS_ConditionVariableWaitUntil (DN_OSConditionVariable *cv, DN_OSMutex *mutex, DN_U64 end_ts_ms); +DN_API void DN_OS_ConditionVariableSignal (DN_OSConditionVariable *cv); +DN_API void DN_OS_ConditionVariableBroadcast (DN_OSConditionVariable *cv); + +DN_API bool DN_OS_ThreadInit (DN_OSThread *thread, DN_OSThreadFunc *func, void *user_context); +DN_API void DN_OS_ThreadDeinit (DN_OSThread *thread); +DN_API DN_U32 DN_OS_ThreadID (); +DN_API void DN_OS_ThreadSetName (DN_Str8 name); + +DN_API void DN_OS_HttpRequestAsync (DN_OSHttpResponse *response, DN_Arena *arena, DN_Str8 host, DN_Str8 path, DN_OSHttpRequestSecure secure, DN_Str8 method, DN_Str8 body, DN_Str8 headers); +DN_API void DN_OS_HttpRequestWait (DN_OSHttpResponse *response); +DN_API void DN_OS_HttpRequestFree (DN_OSHttpResponse *response); +DN_API DN_OSHttpResponse DN_OS_HttpRequest (DN_Arena *arena, DN_Str8 host, DN_Str8 path, DN_OSHttpRequestSecure secure, DN_Str8 method, DN_Str8 body, DN_Str8 headers); +#endif // !defined(DN_OS_H) +// DN: Single header generator commented out this header => #include "OS/dn_os_allocator.h" +#if !defined(DN_OS_ALLOCATOR_H) +#define DN_OS_ALLOCATOR_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +DN_API DN_Arena DN_ArenaFromHeap(DN_U64 size, DN_ArenaFlags flags); +DN_API DN_Arena DN_ArenaFromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags); + +#endif // !defined(DN_OS_ALLOCATOR_H) +// DN: Single header generator commented out this header => #include "OS/dn_os_containers.h" +#if !defined(DN_OS_CONTAINERS_H) +#define DN_OS_CONTAINERS_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +// NOTE: DN_VArray +// TODO(doyle): Add an API for shrinking the array by decomitting pages back to the OS. +template struct DN_VArray +{ + T *data; // Pointer to the start of the array items in the block of memory + DN_USize size; // Number of items currently in the array + DN_USize max; // Maximum number of items this array can store + DN_USize commit; // Bytes committed + + T *begin() { return data; } + T *end () { return data + size; } + T const *begin() const { return data; } + T const *end () const { return data + size; } +}; + +template DN_VArray DN_VArray_InitByteSize (DN_USize byte_size); +template DN_VArray DN_VArray_Init (DN_USize max); +template DN_VArray DN_VArray_InitSlice (DN_Slice slice, DN_USize max); +template DN_VArray DN_VArray_InitCArray (T const (&items)[N], DN_USize max); +template void DN_VArray_Deinit (DN_VArray *array); +template bool DN_VArray_IsValid (DN_VArray const *array); +template DN_Slice DN_VArray_Slice (DN_VArray const *array); +template bool DN_VArray_Reserve (DN_VArray *array, DN_USize count); +template T * DN_VArray_AddArray (DN_VArray *array, T const *items, DN_USize count); +template T * DN_VArray_AddCArray (DN_VArray *array, T const (&items)[N]); +template T * DN_VArray_Add (DN_VArray *array, T const &item); +#define DN_VArray_AddArrayAssert(...) DN_HardAssert(DN_VArray_AddArray(__VA_ARGS__)) +#define DN_VArray_AddCArrayAssert(...) DN_HardAssert(DN_VArray_AddCArray(__VA_ARGS__)) +#define DN_VArray_AddAssert(...) DN_HardAssert(DN_VArray_Add(__VA_ARGS__)) +template T * DN_VArray_MakeArray (DN_VArray *array, DN_USize count, DN_ZMem z_mem); +template T * DN_VArray_Make (DN_VArray *array, DN_ZMem z_mem); +#define DN_VArray_MakeArrayAssert(...) DN_HardAssert(DN_VArray_MakeArray(__VA_ARGS__)) +#define DN_VArray_MakeAssert(...) DN_HardAssert(DN_VArray_Make(__VA_ARGS__)) +template T * DN_VArray_InsertArray (DN_VArray *array, DN_USize index, T const *items, DN_USize count); +template T * DN_VArray_InsertCArray (DN_VArray *array, DN_USize index, T const (&items)[N]); +template T * DN_VArray_Insert (DN_VArray *array, DN_USize index, T const &item); +#define DN_VArray_InsertArrayAssert(...) DN_HardAssert(DN_VArray_InsertArray(__VA_ARGS__)) +#define DN_VArray_InsertCArrayAssert(...) DN_HardAssert(DN_VArray_InsertCArray(__VA_ARGS__)) +#define DN_VArray_InsertAssert(...) DN_HardAssert(DN_VArray_Insert(__VA_ARGS__)) +template T DN_VArray_PopFront (DN_VArray *array, DN_USize count); +template T DN_VArray_PopBack (DN_VArray *array, DN_USize count); +template DN_ArrayEraseResult DN_VArray_EraseRange (DN_VArray *array, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase); +template void DN_VArray_Clear (DN_VArray *array, DN_ZMem z_mem); +#endif // !defined(DN_OS_CONTAINERS_H) +// DN: Single header generator commented out this header => #include "OS/dn_os_print.h" +#if !defined(DN_OS_PRINT_H) +#define DN_OS_PRINT_H + +enum DN_OSPrintDest +{ + DN_OSPrintDest_Out, + DN_OSPrintDest_Err, +}; + +// NOTE: Print Macros +#define DN_OS_PrintOut(string) DN_OS_Print(DN_OSPrintDest_Out, string) +#define DN_OS_PrintOutF(fmt, ...) DN_OS_PrintF(DN_OSPrintDest_Out, fmt, ##__VA_ARGS__) +#define DN_OS_PrintOutFV(fmt, args) DN_OS_PrintFV(DN_OSPrintDest_Out, fmt, args) + +#define DN_OS_PrintOutStyle(style, string) DN_OS_PrintStyle(DN_OSPrintDest_Out, style, string) +#define DN_OS_PrintOutFStyle(style, fmt, ...) DN_OS_PrintFStyle(DN_OSPrintDest_Out, style, fmt, ##__VA_ARGS__) +#define DN_OS_PrintOutFVStyle(style, fmt, args, ...) DN_OS_PrintFVStyle(DN_OSPrintDest_Out, style, fmt, args) + +#define DN_OS_PrintOutLn(string) DN_OS_PrintLn(DN_OSPrintDest_Out, string) +#define DN_OS_PrintOutLnF(fmt, ...) DN_OS_PrintLnF(DN_OSPrintDest_Out, fmt, ##__VA_ARGS__) +#define DN_OS_PrintOutLnFV(fmt, args) DN_OS_PrintLnFV(DN_OSPrintDest_Out, fmt, args) + +#define DN_OS_PrintOutLnStyle(style, string) DN_OS_PrintLnStyle(DN_OSPrintDest_Out, style, string); +#define DN_OS_PrintOutLnFStyle(style, fmt, ...) DN_OS_PrintLnFStyle(DN_OSPrintDest_Out, style, fmt, ##__VA_ARGS__) +#define DN_OS_PrintOutLnFVStyle(style, fmt, args) DN_OS_PrintLnFVStyle(DN_OSPrintDest_Out, style, fmt, args); + +#define DN_OS_PrintErr(string) DN_OS_Print(DN_OSPrintDest_Err, string) +#define DN_OS_PrintErrF(fmt, ...) DN_OS_PrintF(DN_OSPrintDest_Err, fmt, ##__VA_ARGS__) +#define DN_OS_PrintErrFV(fmt, args) DN_OS_PrintFV(DN_OSPrintDest_Err, fmt, args) + +#define DN_OS_PrintErrStyle(style, string) DN_OS_PrintStyle(DN_OSPrintDest_Err, style, string) +#define DN_OS_PrintErrFStyle(style, fmt, ...) DN_OS_PrintFStyle(DN_OSPrintDest_Err, style, fmt, ##__VA_ARGS__) +#define DN_OS_PrintErrFVStyle(style, fmt, args, ...) DN_OS_PrintFVStyle(DN_OSPrintDest_Err, style, fmt, args) + +#define DN_OS_PrintErrLn(string) DN_OS_PrintLn(DN_OSPrintDest_Err, string) +#define DN_OS_PrintErrLnF(fmt, ...) DN_OS_PrintLnF(DN_OSPrintDest_Err, fmt, ##__VA_ARGS__) +#define DN_OS_PrintErrLnFV(fmt, args) DN_OS_PrintLnFV(DN_OSPrintDest_Err, fmt, args) + +#define DN_OS_PrintErrLnStyle(style, string) DN_OS_PrintLnStyle(DN_OSPrintDest_Err, style, string); +#define DN_OS_PrintErrLnFStyle(style, fmt, ...) DN_OS_PrintLnFStyle(DN_OSPrintDest_Err, style, fmt, ##__VA_ARGS__) +#define DN_OS_PrintErrLnFVStyle(style, fmt, args) DN_OS_PrintLnFVStyle(DN_OSPrintDest_Err, style, fmt, args); + +// NOTE: Print +DN_API void DN_OS_Print (DN_OSPrintDest dest, DN_Str8 string); +DN_API void DN_OS_PrintF (DN_OSPrintDest dest, DN_FMT_ATTRIB char const *fmt, ...); +DN_API void DN_OS_PrintFV (DN_OSPrintDest dest, DN_FMT_ATTRIB char const *fmt, va_list args); + +DN_API void DN_OS_PrintStyle (DN_OSPrintDest dest, DN_LOGStyle style, DN_Str8 string); +DN_API void DN_OS_PrintFStyle (DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_ATTRIB char const *fmt, ...); +DN_API void DN_OS_PrintFVStyle (DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_ATTRIB char const *fmt, va_list args); + +DN_API void DN_OS_PrintLn (DN_OSPrintDest dest, DN_Str8 string); +DN_API void DN_OS_PrintLnF (DN_OSPrintDest dest, DN_FMT_ATTRIB char const *fmt, ...); +DN_API void DN_OS_PrintLnFV (DN_OSPrintDest dest, DN_FMT_ATTRIB char const *fmt, va_list args); + +DN_API void DN_OS_PrintLnStyle (DN_OSPrintDest dest, DN_LOGStyle style, DN_Str8 string); +DN_API void DN_OS_PrintLnFStyle (DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_ATTRIB char const *fmt, ...); +DN_API void DN_OS_PrintLnFVStyle (DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_ATTRIB char const *fmt, va_list args); +#endif // !defined(DN_OS_PRINT_H) +// DN: Single header generator commented out this header => #include "OS/dn_os_string.h" +#if !defined(DN_OS_STRING_H) +#define DN_OS_STRING_H + +#if defined(_CLANGD) + // 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" +#endif + +// NOTE: DN_Str8 + +DN_API DN_Str8 DN_Str8FromFmtVArenaFrame (DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API DN_Str8 DN_Str8FromFmtArenaFrame (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8 DN_Str8FromArenaFrame (DN_USize size, DN_ZMem z_mem); +DN_API DN_Str8 DN_Str8FromHeapF (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8 DN_Str8FromHeap (DN_USize size, DN_ZMem z_mem); +DN_API DN_Str8 DN_Str8FromTLSFV (DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API DN_Str8 DN_Str8FromTLSF (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8 DN_Str8FromTLS (DN_USize size, DN_ZMem z_mem); +DN_API DN_Str8 DN_Str8FromStr8Frame (DN_Str8 string); +DN_API DN_Str8 DN_Str8FromStr8TLS (DN_Str8 string); + +DN_API DN_Str8SplitResult DN_Str8SplitFromFrame (DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode); +DN_API DN_Str8SplitResult DN_Str8SplitFromTLS (DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode); + +DN_API DN_Str8 DN_Str8SegmentFromFrame (DN_Str8 src, DN_USize segment_size, char segment_char); +DN_API DN_Str8 DN_Str8SegmentFromTLS (DN_Str8 src, DN_USize segment_size, char segment_char); + +DN_API DN_Str8 DN_Str8ReverseSegmentFromFrame (DN_Str8 src, DN_USize segment_size, char segment_char); +DN_API DN_Str8 DN_Str8ReverseSegmentFromTLS (DN_Str8 src, DN_USize segment_size, char segment_char); + +DN_API DN_Str8 DN_Str8AppendFFromFrame (DN_Str8 string, char const *fmt, ...); +DN_API DN_Str8 DN_Str8AppendFFromTLS (DN_Str8 string, char const *fmt, ...); + +DN_API DN_Str8 DN_Str8FillFFromFrame (DN_Str8 string, char const *fmt, ...); +DN_API DN_Str8 DN_Str8FillFFromTLS (DN_Str8 string, char const *fmt, ...); + +DN_API DN_Str8TruncateResult DN_Str8TruncateMiddleArenaFrame (DN_Str8 str8, uint32_t side_size, DN_Str8 truncator); +DN_API DN_Str8TruncateResult DN_Str8TruncateMiddleArenaTLS (DN_Str8 str8, uint32_t side_size, DN_Str8 truncator); + +DN_API DN_Str8 DN_Str8PadNewLines (DN_Arena *arena, DN_Str8 src, DN_Str8 pad); +DN_API DN_Str8 DN_Str8PadNewLinesFromFrame (DN_Str8 src, DN_Str8 pad); +DN_API DN_Str8 DN_Str8PadNewLinesFromTLS (DN_Str8 src, DN_Str8 pad); + +DN_API DN_Str8 DN_Str8UpperFromFrame (DN_Str8 string); +DN_API DN_Str8 DN_Str8UpperFromTLS (DN_Str8 string); + +DN_API DN_Str8 DN_Str8LowerFromFrame (DN_Str8 string); +DN_API DN_Str8 DN_Str8LowerFromTLS (DN_Str8 string); + +DN_API DN_Str8 DN_Str8Replace (DN_Str8 string, DN_Str8 find, DN_Str8 replace, DN_USize start_index, DN_Arena *arena, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive); +DN_API DN_Str8 DN_Str8ReplaceInsensitive (DN_Str8 string, DN_Str8 find, DN_Str8 replace, DN_USize start_index, DN_Arena *arena); + +// NOTE: DN_Str8Builder //////////////////////////////////////////////////////////////////////////// + +DN_API DN_Str8Builder DN_Str8BuilderFromArena () { return DN_Str8BuilderFromArena(DN_OS_TLSGet()->frame_arena); } +DN_API DN_Str8Builder DN_Str8BuilderFromTLS () { return DN_Str8BuilderFromArena(DN_OS_TLSTopArena()); } + +DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrRefFrame (DN_Str8 const *strings, DN_USize size) { return DN_Str8BuilderFromStr8PtrRef(DN_OS_TLSGet()->frame_arena, strings, size); } +DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrRefTLS (DN_Str8 const *strings, DN_USize size) { return DN_Str8BuilderFromStr8PtrRef(DN_OS_TLSTopArena(), strings, size); } +DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrCopyFrame (DN_Str8 const *strings, DN_USize size) { return DN_Str8BuilderFromStr8PtrCopy(DN_OS_TLSGet()->frame_arena, strings, size); } +DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrCopyTLS (DN_Str8 const *strings, DN_USize size) { return DN_Str8BuilderFromStr8PtrCopy(DN_OS_TLSTopArena(), strings, size); } + +DN_API DN_Str8Builder DN_Str8BuilderFromBuilderFrame (DN_Str8Builder const *builder) { return DN_Str8BuilderFromBuilder(DN_OS_TLSGet()->frame_arena, builder); } +DN_API DN_Str8Builder DN_Str8BuilderFromBuilderTLS (DN_Str8Builder const *builder) { return DN_Str8BuilderFromBuilder(DN_OS_TLSTopArena(), builder); } + +DN_API DN_Str8 DN_Str8BuilderBuildFromFrame (DN_Str8Builder const *builder) { return DN_Str8BuilderBuild(builder, DN_OS_TLSGet()->frame_arena); } +DN_API DN_Str8 DN_Str8BuilderBuildFromHeap (DN_Str8Builder const *builder, DN_Arena *arena); +DN_API DN_Str8 DN_Str8BuilderBuildFromTLS (DN_Str8Builder const *builder) { return DN_Str8BuilderBuild(builder, DN_OS_TLSTopArena()); } + +DN_API DN_Str8 DN_Str8BuilderBuildDelimitedFromFrame(DN_Str8Builder const *builder, DN_Str8 delimiter) { return DN_Str8BuilderBuildDelimited(builder, delimiter, DN_OS_TLSGet()->frame_arena); } +DN_API DN_Str8 DN_Str8BuilderBuildDelimitedFromTLS (DN_Str8Builder const *builder, DN_Str8 delimiter) { return DN_Str8BuilderBuildDelimited(builder, delimiter, DN_OS_TLSTopArena()); } + +DN_API DN_Slice DN_Str8BuilderBuildSliceFromFrame (DN_Str8Builder const *builder) { return DN_Str8BuilderBuildSlice(builder, DN_OS_TLSGet()->frame_arena); } +DN_API DN_Slice DN_Str8BuilderBuildSliceFromTLS (DN_Str8Builder const *builder) { return DN_Str8BuilderBuildSlice(builder, DN_OS_TLSTopArena()); } + +#endif // !defined(DN_OS_STRING_H) + +#endif // DN_OS_INC_H +#endif + struct DN_InitArgs { DN_U64 os_tls_reserve; @@ -10284,12 +18216,23 @@ enum DN_InitFlags_ DN_InitFlags_LogAllFeatures = DN_InitFlags_LogLibFeatures | DN_InitFlags_LogCPUFeatures, }; +struct DN_Core +{ + DN_InitFlags init_flags; + DN_USize mem_allocs_frame; + DN_LeakTracker leak; + #if defined(DN_OS_H) + DN_OSCore os; + #endif +}; + extern DN_Core *g_dn_; DN_API void DN_Init(DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args); DN_API void DN_BeginFrame(); #endif // !defined(DN_INC_H) +#endif DN_Core *g_dn_; @@ -10382,7 +18325,8 @@ static void DN_InitOS_(DN_OSCore *os, DN_InitArgs *args) DN_API void DN_Init(DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args) { - g_dn_ = dn; + g_dn_ = dn; + dn->init_flags = flags; if (flags & DN_InitFlags_OS) { #if defined(DN_OS_H) && defined(DN_OS_CPP) @@ -10472,11 +18416,14 @@ DN_API void DN_BeginFrame() } #define DN_MATH_CPP -// DN: Single header generator commented out this header => #include "dn_math.h" +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "dn_math.h" #if !defined(DN_MATH_H) #define DN_MATH_H -// DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif DN_MSVC_WARNING_PUSH DN_MSVC_WARNING_DISABLE(4201) // warning C4201: nonstandard extension used: nameless struct/union @@ -10845,6 +18792,7 @@ DN_API DN_RaycastLineIntersectV2Result DN_Raycast_LineIntersectV2(DN_V2F32 origi 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); #endif // !defined(DN_MATH_H) +#endif DN_API bool operator==(DN_V2I32 lhs, DN_V2I32 rhs) { @@ -12427,14 +20375,17 @@ DN_API DN_F32 DN_Lerp_F32(DN_F32 a, DN_F32 t, DN_F32 b) } #define DN_ASYNC_CPP -// 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" -// DN: Single header generator commented out this header => #include "dn_async.h" +#if defined(_CLANGD) + // 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" + // DN: Single header generator commented out this header => #include "dn_async.h" #if !defined(DN_ASYNC_H) #define DN_ASYNC_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" +#if defined(_CLANGD) + // 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" +#endif enum DN_ASYNCPriority { @@ -12484,6 +20435,7 @@ DN_API DN_ASYNCTask DN_ASYNC_QueueTask(DN_ASYNCCore *async, DN_ASYNCWorkFunc *fu DN_API void DN_ASYNC_WaitTask (DN_OSSemaphore *sem, DN_U32 timeout_ms); #endif // DN_ASYNC_H +#endif static DN_I32 DN_ASYNC_ThreadEntryPoint_(DN_OSThread *thread) { @@ -12602,6 +20554,59 @@ DN_API bool DN_ASYNC_WaitTask(DN_ASYNCTask *task, DN_U32 timeout_ms) return result; } +#define DN_BIN_PACK_CPP + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "dn_bin_pack.h" +#if !defined(DN_BIN_PACK_H) +#define DN_BIN_PACK_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +#if !defined(DN_BASE_INC_H) + #error dn_base_inc.h must be included before this +#endif + +enum DN_BinPackMode +{ + DN_BinPackMode_Serialise, + DN_BinPackMode_Deserialise, +}; + +struct DN_BinPack +{ + DN_Str8Builder writer; + DN_Str8 read; + DN_USize read_index; +}; + +DN_API void DN_BinPack_U64 (DN_BinPack *pack, DN_BinPackMode mode, DN_U64 *item); +DN_API void DN_BinPack_U32 (DN_BinPack *pack, DN_BinPackMode mode, DN_U32 *item); +DN_API void DN_BinPack_U16 (DN_BinPack *pack, DN_BinPackMode mode, DN_U16 *item); +DN_API void DN_BinPack_U8 (DN_BinPack *pack, DN_BinPackMode mode, DN_U8 *item); +DN_API void DN_BinPack_I64 (DN_BinPack *pack, DN_BinPackMode mode, DN_I64 *item); +DN_API void DN_BinPack_I32 (DN_BinPack *pack, DN_BinPackMode mode, DN_I32 *item); +DN_API void DN_BinPack_I16 (DN_BinPack *pack, DN_BinPackMode mode, DN_I16 *item); +DN_API void DN_BinPack_I8 (DN_BinPack *pack, DN_BinPackMode mode, DN_I8 *item); +DN_API void DN_BinPack_F64 (DN_BinPack *pack, DN_BinPackMode mode, DN_F64 *item); +DN_API void DN_BinPack_F32 (DN_BinPack *pack, DN_BinPackMode mode, DN_F32 *item); +#if defined(DN_MATH_H) +DN_API void DN_BinPack_V2 (DN_BinPack *pack, DN_BinPackMode mode, DN_V2F32 *item); +DN_API void DN_BinPack_V4 (DN_BinPack *pack, DN_BinPackMode mode, DN_V4F32 *item); +#endif +DN_API void DN_BinPack_Bool (DN_BinPack *pack, DN_BinPackMode mode, bool *item); +DN_API void DN_BinPack_Str8FromArena (DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, DN_Str8 *string); +DN_API void DN_BinPack_Str8FromPool (DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, DN_Str8 *string); +DN_API void DN_BinPack_BytesFromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, void **ptr, DN_USize *size); +DN_API void DN_BinPack_BytesFromPool (DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, void **ptr, DN_USize *size); +DN_API void DN_BinPack_CArray (DN_BinPack *pack, DN_BinPackMode mode, void *ptr, DN_USize size); +DN_API DN_Str8 DN_BinPack_Build (DN_BinPack const *pack, DN_Arena *arena); + +#endif // !defined(DN_BIN_PACK_H) +#endif + DN_API void DN_BinPack_U64(DN_BinPack *pack, DN_BinPackMode mode, DN_U64 *item) { DN_U64 const VALUE_MASK = 0b0111'1111; @@ -12767,10 +20772,17 @@ DN_API DN_Str8 DN_BinPack_Build(DN_BinPack const *pack, DN_Arena *arena) DN_Str8 result = DN_Str8BuilderBuild(&pack->writer, arena); return result; } -// DN: Single header generator commented out this header => #include "dn_csv.h" +#define DN_CSV_CPP + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "dn_csv.h" #if !defined(DN_CSV_H) #define DN_CSV_H +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + enum DN_CSVSerialise { DN_CSVSerialise_Read, @@ -12794,6 +20806,7 @@ struct DN_CSVPack }; #endif // !defined(DN_CSV_H) +#endif static DN_CSVTokeniser DN_CSV_TokeniserInit(DN_Str8 string, char delimiter) { @@ -13083,6 +21096,59 @@ static bool DN_CSV_PackNewLine(DN_CSVPack *pack, DN_CSVSerialise serialise) DN_MSVC_WARNING_POP #define DN_HASH_CPP +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "dn_hash.h" +#if !defined(DN_HASH_H) +#define DN_HASH_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +/* +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// $$\ $$\ $$$$$$\ $$$$$$\ $$\ $$\ +// $$ | $$ |$$ __$$\ $$ __$$\ $$ | $$ | +// $$ | $$ |$$ / $$ |$$ / \__|$$ | $$ | +// $$$$$$$$ |$$$$$$$$ |\$$$$$$\ $$$$$$$$ | +// $$ __$$ |$$ __$$ | \____$$\ $$ __$$ | +// $$ | $$ |$$ | $$ |$$\ $$ |$$ | $$ | +// $$ | $$ |$$ | $$ |\$$$$$$ |$$ | $$ | +// \__| \__|\__| \__| \______/ \__| \__| +// +// dn_hash.h -- Hashing functions +// +//////////////////////////////////////////////////////////////////////////////////////////////////// +*/ + +// NOTE: DN_FNV1A ////////////////////////////////////////////////////////////////////////////////// +#if !defined(DN_FNV1A32_SEED) + #define DN_FNV1A32_SEED 2166136261U +#endif + +#if !defined(DN_FNV1A64_SEED) + #define DN_FNV1A64_SEED 14695981039346656037ULL +#endif + +// NOTE: DN_MurmurHash3 //////////////////////////////////////////////////////////////////////////// +struct DN_MurmurHash3 { uint64_t e[2]; }; + +// NOTE: DN_FNV1A ////////////////////////////////////////////////////////////////////////////////// +DN_API uint32_t DN_FNV1A32_Hash (void const *bytes, DN_USize size); +DN_API uint64_t DN_FNV1A64_Hash (void const *bytes, DN_USize size); +DN_API uint32_t DN_FNV1A32_Iterate (void const *bytes, DN_USize size, uint32_t hash); +DN_API uint64_t DN_FNV1A64_Iterate (void const *bytes, DN_USize size, uint64_t hash); + +// NOTE: DN_MurmurHash3 //////////////////////////////////////////////////////////////////////////// +DN_API uint32_t DN_MurmurHash3_x86U32 (void const *key, int len, uint32_t seed); +DN_API DN_MurmurHash3 DN_MurmurHash3_x64U128 (void const *key, int len, uint32_t seed); +#define DN_MurmurHash3_x64U128AsU64(key, len, seed) (DN_MurmurHash3_x64U128(key, len, seed).e[0]) +#define DN_MurmurHash3_x64U128AsU32(key, len, seed) (DN_Cast(uint32_t)DN_MurmurHash3_x64U128(key, len, seed).e[0]) + +#endif // !defined(DN_HASH_H) +#endif + /* //////////////////////////////////////////////////////////////////////////////////////////////////// // @@ -13100,33 +21166,33 @@ DN_MSVC_WARNING_POP //////////////////////////////////////////////////////////////////////////////////////////////////// */ -// NOTE: DN_FNV1A ////////////////////////////////////////////////////////////////////////////////// +// NOTE: DN_FNV1A // Default values recommended by: http://isthe.com/chongo/tech/comp/fnv/ -DN_API uint32_t DN_FNV1A32_Iterate(void const *bytes, DN_USize size, uint32_t hash) +DN_API DN_U32 DN_FNV1A32_Iterate(void const *bytes, DN_USize size, DN_U32 hash) { - auto buffer = DN_Cast(uint8_t const *)bytes; + auto buffer = DN_Cast(DN_U8 const *)bytes; for (DN_USize i = 0; i < size; i++) hash = (buffer[i] ^ hash) * 16777619 /*FNV Prime*/; return hash; } -DN_API uint32_t DN_FNV1A32_Hash(void const *bytes, DN_USize size) +DN_API DN_U32 DN_FNV1A32_Hash(void const *bytes, DN_USize size) { - uint32_t result = DN_FNV1A32_Iterate(bytes, size, DN_FNV1A32_SEED); + DN_U32 result = DN_FNV1A32_Iterate(bytes, size, DN_FNV1A32_SEED); return result; } -DN_API uint64_t DN_FNV1A64_Iterate(void const *bytes, DN_USize size, uint64_t hash) +DN_API DN_U64 DN_FNV1A64_Iterate(void const *bytes, DN_USize size, DN_U64 hash) { - auto buffer = DN_Cast(uint8_t const *)bytes; + auto buffer = DN_Cast(DN_U8 const *)bytes; for (DN_USize i = 0; i < size; i++) hash = (buffer[i] ^ hash) * 1099511628211 /*FNV Prime*/; return hash; } -DN_API uint64_t DN_FNV1A64_Hash(void const *bytes, DN_USize size) +DN_API DN_U64 DN_FNV1A64_Hash(void const *bytes, DN_USize size) { - uint64_t result = DN_FNV1A64_Iterate(bytes, size, DN_FNV1A64_SEED); + DN_U64 result = DN_FNV1A64_Iterate(bytes, size, DN_FNV1A64_SEED); return result; } @@ -13143,12 +21209,12 @@ DN_API uint64_t DN_FNV1A64_Hash(void const *bytes, DN_USize size) // Block read - if your platform needs to do endian-swapping or can only // handle aligned reads, do the conversion here -DN_FORCE_INLINE uint32_t DN_MurmurHash3_GetBlock32(uint32_t const *p, int i) +DN_FORCE_INLINE DN_U32 DN_MurmurHash3_GetBlock32(DN_U32 const *p, int i) { return p[i]; } -DN_FORCE_INLINE uint64_t DN_MurmurHash3_GetBlock64(uint64_t const *p, int i) +DN_FORCE_INLINE DN_U64 DN_MurmurHash3_GetBlock64(DN_U64 const *p, int i) { return p[i]; } @@ -13156,7 +21222,7 @@ DN_FORCE_INLINE uint64_t DN_MurmurHash3_GetBlock64(uint64_t const *p, int i) //----------------------------------------------------------------------------- // Finalization mix - force all bits of a hash block to avalanche -DN_FORCE_INLINE uint32_t DN_MurmurHash3_FMix32(uint32_t h) +DN_FORCE_INLINE DN_U32 DN_MurmurHash3_FMix32(DN_U32 h) { h ^= h >> 16; h *= 0x85ebca6b; @@ -13166,7 +21232,7 @@ DN_FORCE_INLINE uint32_t DN_MurmurHash3_FMix32(uint32_t h) return h; } -DN_FORCE_INLINE uint64_t DN_MurmurHash3_FMix64(uint64_t k) +DN_FORCE_INLINE DN_U64 DN_MurmurHash3_FMix64(DN_U64 k) { k ^= k >> 33; k *= 0xff51afd7ed558ccd; @@ -13176,24 +21242,24 @@ DN_FORCE_INLINE uint64_t DN_MurmurHash3_FMix64(uint64_t k) return k; } -DN_API uint32_t DN_MurmurHash3_x86U32(void const *key, int len, uint32_t seed) +DN_API DN_U32 DN_MurmurHash3_x86U32(void const *key, int len, DN_U32 seed) { - const uint8_t *data = (const uint8_t *)key; + const DN_U8 *data = (const DN_U8 *)key; const int nblocks = len / 4; - uint32_t h1 = seed; + DN_U32 h1 = seed; - const uint32_t c1 = 0xcc9e2d51; - const uint32_t c2 = 0x1b873593; + const DN_U32 c1 = 0xcc9e2d51; + const DN_U32 c2 = 0x1b873593; //---------- // body - const uint32_t *blocks = (const uint32_t *)(data + nblocks * 4); + const DN_U32 *blocks = (const DN_U32 *)(data + nblocks * 4); for (int i = -nblocks; i; i++) { - uint32_t k1 = DN_MurmurHash3_GetBlock32(blocks, i); + DN_U32 k1 = DN_MurmurHash3_GetBlock32(blocks, i); k1 *= c1; k1 = DN_MMH3_ROTL32(k1, 15); @@ -13207,9 +21273,9 @@ DN_API uint32_t DN_MurmurHash3_x86U32(void const *key, int len, uint32_t seed) //---------- // tail - const uint8_t *tail = (const uint8_t *)(data + nblocks * 4); + const DN_U8 *tail = (const DN_U8 *)(data + nblocks * 4); - uint32_t k1 = 0; + DN_U32 k1 = 0; switch (len & 3) { @@ -13235,26 +21301,26 @@ DN_API uint32_t DN_MurmurHash3_x86U32(void const *key, int len, uint32_t seed) return h1; } -DN_API DN_MurmurHash3 DN_MurmurHash3_x64U128(void const *key, int len, uint32_t seed) +DN_API DN_MurmurHash3 DN_MurmurHash3_x64U128(void const *key, int len, DN_U32 seed) { - const uint8_t *data = (const uint8_t *)key; + const DN_U8 *data = (const DN_U8 *)key; const int nblocks = len / 16; - uint64_t h1 = seed; - uint64_t h2 = seed; + DN_U64 h1 = seed; + DN_U64 h2 = seed; - const uint64_t c1 = 0x87c37b91114253d5; - const uint64_t c2 = 0x4cf5ad432745937f; + const DN_U64 c1 = 0x87c37b91114253d5; + const DN_U64 c2 = 0x4cf5ad432745937f; //---------- // body - const uint64_t *blocks = (const uint64_t *)(data); + const DN_U64 *blocks = (const DN_U64 *)(data); for (int i = 0; i < nblocks; i++) { - uint64_t k1 = DN_MurmurHash3_GetBlock64(blocks, i * 2 + 0); - uint64_t k2 = DN_MurmurHash3_GetBlock64(blocks, i * 2 + 1); + DN_U64 k1 = DN_MurmurHash3_GetBlock64(blocks, i * 2 + 0); + DN_U64 k2 = DN_MurmurHash3_GetBlock64(blocks, i * 2 + 1); k1 *= c1; k1 = DN_MMH3_ROTL64(k1, 31); @@ -13278,48 +21344,48 @@ DN_API DN_MurmurHash3 DN_MurmurHash3_x64U128(void const *key, int len, uint32_t //---------- // tail - const uint8_t *tail = (const uint8_t *)(data + nblocks * 16); + const DN_U8 *tail = (const DN_U8 *)(data + nblocks * 16); - uint64_t k1 = 0; - uint64_t k2 = 0; + DN_U64 k1 = 0; + DN_U64 k2 = 0; switch (len & 15) { case 15: - k2 ^= ((uint64_t)tail[14]) << 48; + k2 ^= ((DN_U64)tail[14]) << 48; case 14: - k2 ^= ((uint64_t)tail[13]) << 40; + k2 ^= ((DN_U64)tail[13]) << 40; case 13: - k2 ^= ((uint64_t)tail[12]) << 32; + k2 ^= ((DN_U64)tail[12]) << 32; case 12: - k2 ^= ((uint64_t)tail[11]) << 24; + k2 ^= ((DN_U64)tail[11]) << 24; case 11: - k2 ^= ((uint64_t)tail[10]) << 16; + k2 ^= ((DN_U64)tail[10]) << 16; case 10: - k2 ^= ((uint64_t)tail[9]) << 8; + k2 ^= ((DN_U64)tail[9]) << 8; case 9: - k2 ^= ((uint64_t)tail[8]) << 0; + k2 ^= ((DN_U64)tail[8]) << 0; k2 *= c2; k2 = DN_MMH3_ROTL64(k2, 33); k2 *= c1; h2 ^= k2; case 8: - k1 ^= ((uint64_t)tail[7]) << 56; + k1 ^= ((DN_U64)tail[7]) << 56; case 7: - k1 ^= ((uint64_t)tail[6]) << 48; + k1 ^= ((DN_U64)tail[6]) << 48; case 6: - k1 ^= ((uint64_t)tail[5]) << 40; + k1 ^= ((DN_U64)tail[5]) << 40; case 5: - k1 ^= ((uint64_t)tail[4]) << 32; + k1 ^= ((DN_U64)tail[4]) << 32; case 4: - k1 ^= ((uint64_t)tail[3]) << 24; + k1 ^= ((DN_U64)tail[3]) << 24; case 3: - k1 ^= ((uint64_t)tail[2]) << 16; + k1 ^= ((DN_U64)tail[2]) << 16; case 2: - k1 ^= ((uint64_t)tail[1]) << 8; + k1 ^= ((DN_U64)tail[1]) << 8; case 1: - k1 ^= ((uint64_t)tail[0]) << 0; + k1 ^= ((DN_U64)tail[0]) << 0; k1 *= c1; k1 = DN_MMH3_ROTL64(k1, 31); k1 *= c2; @@ -13348,6 +21414,671 @@ DN_API DN_MurmurHash3 DN_MurmurHash3_x64U128(void const *key, int len, uint32_t } #define DN_HELPERS_CPP +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "dn_helpers.h" +#if !defined(DN_HELPERS_H) +#define DN_HELPERS_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" + // DN: Single header generator commented out this header => #include "dn_math.h" +#if !defined(DN_MATH_H) +#define DN_MATH_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +DN_MSVC_WARNING_PUSH +DN_MSVC_WARNING_DISABLE(4201) // warning C4201: nonstandard extension used: nameless struct/union +union DN_V2I32 +{ + struct { DN_I32 x, y; }; + struct { DN_I32 w, h; }; + DN_I32 data[2]; +}; + +union DN_V2U16 +{ + struct { DN_U16 x, y; }; + struct { DN_U16 w, h; }; + DN_U16 data[2]; +}; + +union DN_V2U32 +{ + struct { DN_U32 x, y; }; + struct { DN_U32 w, h; }; + DN_U32 data[2]; +}; + +union DN_V2F32 +{ + struct { DN_F32 x, y; }; + struct { DN_F32 w, h; }; + DN_F32 data[2]; +}; + +union DN_V3F32 +{ + struct { DN_F32 x, y, z; }; + struct { DN_F32 r, g, b; }; + DN_F32 data[3]; +}; + + +union DN_V4F32 +{ + struct { DN_F32 x, y, z, w; }; + struct { DN_F32 r, g, b, a; }; + #if !defined(DN_NO_V3) + DN_V3F32 rgb; + DN_V3F32 xyz; + #endif + DN_F32 data[4]; +}; +DN_MSVC_WARNING_POP + +struct DN_M4 +{ + DN_F32 columns[4][4]; // Column major matrix +}; + +union DN_M2x3 +{ + DN_F32 e[6]; + DN_F32 row[2][3]; +}; + +struct DN_Rect +{ + DN_V2F32 pos, size; +}; + +struct DN_RectMinMax +{ + DN_V2F32 min, max; +}; + +enum DN_RectCutClip +{ + DN_RectCutClip_No, + DN_RectCutClip_Yes, +}; + +enum DN_RectCutSide +{ + DN_RectCutSide_Left, + DN_RectCutSide_Right, + DN_RectCutSide_Top, + DN_RectCutSide_Bottom, +}; + +struct DN_RectCut +{ + DN_Rect* rect; + DN_RectCutSide side; +}; + +struct DN_RaycastLineIntersectV2Result +{ + bool hit; // True if there was an intersection, false if the lines are parallel + DN_F32 t_a; // Distance along `dir_a` that the intersection occurred, e.g. `origin_a + (dir_a * t_a)` + DN_F32 t_b; // Distance along `dir_b` that the intersection occurred, e.g. `origin_b + (dir_b * t_b)` +}; + +#define DN_V2I32_Zero DN_Literal(DN_V2I32){{(int32_t)(0), (int32_t)(0)}} +#define DN_V2I32_One DN_Literal(DN_V2I32){{(int32_t)(1), (int32_t)(1)}} +#define DN_V2I32_From1N(x) DN_Literal(DN_V2I32){{(int32_t)(x), (int32_t)(x)}} +#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); +DN_API bool operator< (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API bool operator> (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API DN_V2I32 operator- (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API DN_V2I32 operator- (DN_V2I32 lhs); +DN_API DN_V2I32 operator+ (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API DN_V2I32 operator* (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API DN_V2I32 operator* (DN_V2I32 lhs, DN_F32 rhs); +DN_API DN_V2I32 operator* (DN_V2I32 lhs, int32_t rhs); +DN_API DN_V2I32 operator/ (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API DN_V2I32 operator/ (DN_V2I32 lhs, DN_F32 rhs); +DN_API DN_V2I32 operator/ (DN_V2I32 lhs, int32_t rhs); +DN_API DN_V2I32 & operator*= (DN_V2I32& lhs, DN_V2I32 rhs); +DN_API DN_V2I32 & operator*= (DN_V2I32& lhs, DN_F32 rhs); +DN_API DN_V2I32 & operator*= (DN_V2I32& lhs, int32_t rhs); +DN_API DN_V2I32 & operator/= (DN_V2I32& lhs, DN_V2I32 rhs); +DN_API DN_V2I32 & operator/= (DN_V2I32& lhs, DN_F32 rhs); +DN_API DN_V2I32 & operator/= (DN_V2I32& lhs, int32_t rhs); +DN_API DN_V2I32 & operator-= (DN_V2I32& lhs, DN_V2I32 rhs); +DN_API DN_V2I32 & operator+= (DN_V2I32& lhs, DN_V2I32 rhs); + +DN_API DN_V2I32 DN_V2I32_Min (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); + +#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_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)}} + +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); +DN_API bool operator< (DN_V2U16 lhs, DN_V2U16 rhs); +DN_API bool 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); +DN_API DN_V2U16 operator* (DN_V2U16 lhs, DN_F32 rhs); +DN_API DN_V2U16 operator* (DN_V2U16 lhs, int32_t rhs); +DN_API DN_V2U16 operator/ (DN_V2U16 lhs, DN_V2U16 rhs); +DN_API DN_V2U16 operator/ (DN_V2U16 lhs, DN_F32 rhs); +DN_API DN_V2U16 operator/ (DN_V2U16 lhs, int32_t rhs); +DN_API DN_V2U16 & operator*= (DN_V2U16& lhs, DN_V2U16 rhs); +DN_API DN_V2U16 & operator*= (DN_V2U16& lhs, DN_F32 rhs); +DN_API DN_V2U16 & operator*= (DN_V2U16& lhs, int32_t rhs); +DN_API DN_V2U16 & operator/= (DN_V2U16& lhs, DN_V2U16 rhs); +DN_API DN_V2U16 & operator/= (DN_V2U16& lhs, DN_F32 rhs); +DN_API DN_V2U16 & operator/= (DN_V2U16& lhs, int32_t 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_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_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_FromV2U32(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); +DN_API bool operator< (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API bool operator> (DN_V2F32 lhs, DN_V2F32 rhs); + +DN_API DN_V2F32 operator- (DN_V2F32 lhs); +DN_API DN_V2F32 operator- (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API DN_V2F32 operator- (DN_V2F32 lhs, DN_V2I32 rhs); +DN_API DN_V2F32 operator- (DN_V2F32 lhs, DN_F32 rhs); +DN_API DN_V2F32 operator- (DN_V2F32 lhs, int32_t rhs); + +DN_API DN_V2F32 operator+ (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API DN_V2F32 operator+ (DN_V2F32 lhs, DN_V2I32 rhs); +DN_API DN_V2F32 operator+ (DN_V2F32 lhs, DN_F32 rhs); +DN_API DN_V2F32 operator+ (DN_V2F32 lhs, int32_t rhs); + +DN_API DN_V2F32 operator* (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API DN_V2F32 operator* (DN_V2F32 lhs, DN_V2I32 rhs); +DN_API DN_V2F32 operator* (DN_V2F32 lhs, DN_F32 rhs); +DN_API DN_V2F32 operator* (DN_V2F32 lhs, int32_t rhs); + +DN_API DN_V2F32 operator/ (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API DN_V2F32 operator/ (DN_V2F32 lhs, DN_V2I32 rhs); +DN_API DN_V2F32 operator/ (DN_V2F32 lhs, DN_F32 rhs); +DN_API DN_V2F32 operator/ (DN_V2F32 lhs, int32_t rhs); + +DN_API DN_V2F32 & operator*= (DN_V2F32& lhs, DN_V2F32 rhs); +DN_API DN_V2F32 & operator*= (DN_V2F32& lhs, DN_V2I32 rhs); +DN_API DN_V2F32 & operator*= (DN_V2F32& lhs, DN_F32 rhs); +DN_API DN_V2F32 & operator*= (DN_V2F32& lhs, int32_t rhs); + +DN_API DN_V2F32 & operator/= (DN_V2F32& lhs, DN_V2F32 rhs); +DN_API DN_V2F32 & operator/= (DN_V2F32& lhs, DN_V2I32 rhs); +DN_API DN_V2F32 & operator/= (DN_V2F32& lhs, DN_F32 rhs); +DN_API DN_V2F32 & operator/= (DN_V2F32& lhs, int32_t rhs); + +DN_API DN_V2F32 & operator-= (DN_V2F32& lhs, DN_V2F32 rhs); +DN_API DN_V2F32 & operator-= (DN_V2F32& lhs, DN_V2I32 rhs); +DN_API DN_V2F32 & operator-= (DN_V2F32& lhs, DN_F32 rhs); +DN_API DN_V2F32 & operator-= (DN_V2F32& lhs, int32_t rhs); + +DN_API DN_V2F32 & operator+= (DN_V2F32& lhs, DN_V2F32 rhs); +DN_API DN_V2F32 & operator+= (DN_V2F32& lhs, DN_V2I32 rhs); +DN_API DN_V2F32 & operator+= (DN_V2F32& lhs, DN_F32 rhs); +DN_API DN_V2F32 & operator+= (DN_V2F32& lhs, int32_t rhs); + +DN_API DN_V2F32 DN_V2F32_Min (DN_V2F32 a, DN_V2F32 b); +DN_API DN_V2F32 DN_V2F32_Max (DN_V2F32 a, DN_V2F32 b); +DN_API DN_V2F32 DN_V2F32_Abs (DN_V2F32 a); +DN_API DN_F32 DN_V2F32_Dot (DN_V2F32 a, DN_V2F32 b); +DN_API DN_F32 DN_V2F32_LengthSq2V2 (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API bool DN_V2F32_LengthSqIsWithin2V2 (DN_V2F32 lhs, DN_V2F32 rhs, DN_F32 within_amount_sq); +DN_API DN_F32 DN_V2F32_Length2V2 (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API DN_F32 DN_V2F32_LengthSq (DN_V2F32 lhs); +DN_API DN_F32 DN_V2F32_Length (DN_V2F32 lhs); +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_Reflect (DN_V2F32 in, DN_V2F32 surface); +DN_API DN_F32 DN_V2F32_Area (DN_V2F32 a); + +#define DN_V3F32_From1N(x) DN_Literal(DN_V3F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}} +#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); +DN_API bool operator< (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API bool operator> (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API DN_V3F32 operator- (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API DN_V3F32 operator- (DN_V3F32 lhs); +DN_API DN_V3F32 operator+ (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API DN_V3F32 operator* (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API DN_V3F32 operator* (DN_V3F32 lhs, DN_F32 rhs); +DN_API DN_V3F32 operator* (DN_V3F32 lhs, int32_t rhs); +DN_API DN_V3F32 operator/ (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API DN_V3F32 operator/ (DN_V3F32 lhs, DN_F32 rhs); +DN_API DN_V3F32 operator/ (DN_V3F32 lhs, int32_t rhs); +DN_API DN_V3F32 & operator*= (DN_V3F32 &lhs, DN_V3F32 rhs); +DN_API DN_V3F32 & operator*= (DN_V3F32 &lhs, DN_F32 rhs); +DN_API DN_V3F32 & operator*= (DN_V3F32 &lhs, int32_t rhs); +DN_API DN_V3F32 & operator/= (DN_V3F32 &lhs, DN_V3F32 rhs); +DN_API DN_V3F32 & operator/= (DN_V3F32 &lhs, DN_F32 rhs); +DN_API DN_V3F32 & operator/= (DN_V3F32 &lhs, int32_t rhs); +DN_API DN_V3F32 & operator-= (DN_V3F32 &lhs, DN_V3F32 rhs); +DN_API DN_V3F32 & operator+= (DN_V3F32 &lhs, DN_V3F32 rhs); +DN_API DN_F32 DN_V3F32_LengthSq (DN_V3F32 a); +DN_API DN_F32 DN_V3F32_Length (DN_V3F32 a); +DN_API DN_V3F32 DN_V3F32_Normalise (DN_V3F32 a); + +DN_U32 const DN_V4_R_MASK_U32 = 0xFF000000; +DN_U32 const DN_V4_G_MASK_U32 = 0x00FF0000; +DN_U32 const DN_V4_B_MASK_U32 = 0x0000FF00; +DN_U32 const DN_V4_A_MASK_U32 = 0x000000FF; + +#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_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_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_FromRGBAU32(DN_U32 u32); +#define DN_V4F32_FromV4Alpha(v4, alpha) DN_V4F32_FromV3And1N(v4.xyz, alpha) +DN_API bool operator== (DN_V4F32 lhs, DN_V4F32 rhs); +DN_API bool operator!= (DN_V4F32 lhs, DN_V4F32 rhs); +DN_API bool operator<= (DN_V4F32 lhs, DN_V4F32 rhs); +DN_API bool operator< (DN_V4F32 lhs, DN_V4F32 rhs); +DN_API bool 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_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_F32 rhs); +DN_API DN_V4F32 operator* (DN_V4F32 lhs, int32_t rhs); +DN_API DN_V4F32 operator/ (DN_V4F32 lhs, DN_F32 rhs); +DN_API DN_V4F32 & operator*= (DN_V4F32 &lhs, DN_V4F32 rhs); +DN_API DN_V4F32 & operator*= (DN_V4F32 &lhs, DN_F32 rhs); +DN_API DN_V4F32 & operator*= (DN_V4F32 &lhs, int32_t 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_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_Scale (DN_V3F32 xyz); +DN_API DN_M4 DN_M4_TranslateF (DN_F32 x, DN_F32 y, DN_F32 z); +DN_API DN_M4 DN_M4_Translate (DN_V3F32 xyz); +DN_API DN_M4 DN_M4_Transpose (DN_M4 mat); +DN_API DN_M4 DN_M4_Rotate (DN_V3F32 axis, DN_F32 radians); +DN_API DN_M4 DN_M4_Orthographic (DN_F32 left, DN_F32 right, DN_F32 bottom, DN_F32 top, DN_F32 z_near, DN_F32 z_far); +DN_API DN_M4 DN_M4_Perspective (DN_F32 fov /*radians*/, DN_F32 aspect, DN_F32 z_near, DN_F32 z_far); +DN_API DN_M4 DN_M4_Add (DN_M4 lhs, DN_M4 rhs); +DN_API DN_M4 DN_M4_Sub (DN_M4 lhs, DN_M4 rhs); +DN_API DN_M4 DN_M4_Mul (DN_M4 lhs, DN_M4 rhs); +DN_API DN_M4 DN_M4_Div (DN_M4 lhs, DN_M4 rhs); +DN_API DN_M4 DN_M4_AddF (DN_M4 lhs, DN_F32 rhs); +DN_API DN_M4 DN_M4_SubF (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_Str8x256 DN_M4_ColumnMajorString (DN_M4 mat); + +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_Translate (DN_V2F32 offset); +DN_API DN_M2x3 DN_M2x3_Scale (DN_V2F32 scale); +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_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); + +#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}}} + +DN_API bool operator== (const DN_Rect& lhs, const DN_Rect& rhs); +DN_API DN_V2F32 DN_Rect_Center (DN_Rect rect); +DN_API bool DN_Rect_ContainsPoint (DN_Rect rect, DN_V2F32 p); +DN_API bool DN_Rect_ContainsRect (DN_Rect a, DN_Rect b); +DN_API DN_Rect DN_Rect_Expand (DN_Rect a, DN_F32 amount); +DN_API DN_Rect DN_Rect_ExpandV2 (DN_Rect a, DN_V2F32 amount); +DN_API bool DN_Rect_Intersects (DN_Rect a, DN_Rect b); +DN_API DN_Rect DN_Rect_Intersection (DN_Rect a, DN_Rect b); +DN_API DN_Rect DN_Rect_Union (DN_Rect a, DN_Rect b); +DN_API DN_RectMinMax DN_Rect_MinMax (DN_Rect a); +DN_API DN_F32 DN_Rect_Area (DN_Rect a); +DN_API DN_V2F32 DN_Rect_InterpolatedPoint (DN_Rect rect, DN_V2F32 t01); +DN_API DN_V2F32 DN_Rect_TopLeft (DN_Rect rect); +DN_API DN_V2F32 DN_Rect_TopRight (DN_Rect rect); +DN_API DN_V2F32 DN_Rect_BottomLeft (DN_Rect rect); +DN_API DN_V2F32 DN_Rect_BottomRight (DN_Rect rect); + +DN_API DN_Rect DN_Rect_CutLeftClip (DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip); +DN_API DN_Rect DN_Rect_CutRightClip (DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip); +DN_API DN_Rect DN_Rect_CutTopClip (DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip); +DN_API DN_Rect DN_Rect_CutBottomClip (DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip); + +#define DN_Rect_CutLeft(rect, amount) DN_Rect_CutLeftClip(rect, amount, DN_RectCutClip_Yes) +#define DN_Rect_CutRight(rect, amount) DN_Rect_CutRightClip(rect, amount, DN_RectCutClip_Yes) +#define DN_Rect_CutTop(rect, amount) DN_Rect_CutTopClip(rect, amount, DN_RectCutClip_Yes) +#define DN_Rect_CutBottom(rect, amount) DN_Rect_CutBottomClip(rect, amount, DN_RectCutClip_Yes) + +#define DN_Rect_CutLeftNoClip(rect, amount) DN_Rect_CutLeftClip(rect, amount, DN_RectCutClip_No) +#define DN_Rect_CutRightNoClip(rect, amount) DN_Rect_CutRightClip(rect, amount, DN_RectCutClip_No) +#define DN_Rect_CutTopNoClip(rect, amount) DN_Rect_CutTopClip(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); +#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_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_Bottom(rect) DN_Literal(DN_RectCut){rect, DN_RectCutSide_Bottom} + +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_F32 DN_Lerp_F32 (DN_F32 a, DN_F32 t, DN_F32 b); +#endif // !defined(DN_MATH_H) +#endif + +#if !defined(DN_BASE_H) + #error dn_base_inc.h must be included before this +#endif + +#if !defined(DN_MATH_H) + #error dn_math.h must be included before this +#endif + +/* +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// $$\ $$\ $$$$$$$$\ $$\ $$$$$$$\ $$$$$$$$\ $$$$$$$\ $$$$$$\ +// $$ | $$ |$$ _____|$$ | $$ __$$\ $$ _____|$$ __$$\ $$ __$$\ +// $$ | $$ |$$ | $$ | $$ | $$ |$$ | $$ | $$ |$$ / \__| +// $$$$$$$$ |$$$$$\ $$ | $$$$$$$ |$$$$$\ $$$$$$$ |\$$$$$$\ +// $$ __$$ |$$ __| $$ | $$ ____/ $$ __| $$ __$$< \____$$\ +// $$ | $$ |$$ | $$ | $$ | $$ | $$ | $$ |$$\ $$ | +// $$ | $$ |$$$$$$$$\ $$$$$$$$\ $$ | $$$$$$$$\ $$ | $$ |\$$$$$$ | +// \__| \__|\________|\________|\__| \________|\__| \__| \______/ +// +// dn_helpers.h -- Helper functions/data structures +// +//////////////////////////////////////////////////////////////////////////////////////////////////// +*/ + +// NOTE: DN_PCG32 ////////////////////////////////////////////////////////////////////////////////// +struct DN_PCG32 { uint64_t state; }; + +#if !defined(DN_NO_JSON_BUILDER) +// NOTE: DN_JSONBuilder //////////////////////////////////////////////////////////////////////////// +enum DN_JSONBuilderItem +{ + DN_JSONBuilderItem_Empty, + DN_JSONBuilderItem_OpenContainer, + DN_JSONBuilderItem_CloseContainer, + DN_JSONBuilderItem_KeyValue, +}; + +struct DN_JSONBuilder +{ + bool use_stdout; // When set, ignore the string builder and dump immediately to stdout + DN_Str8Builder string_builder; // (Internal) + int indent_level; // (Internal) + int spaces_per_indent; // The number of spaces per indent level + DN_JSONBuilderItem last_item; +}; +#endif // !defined(DN_NO_JSON_BUIDLER) + +// NOTE: DN_BinarySearch /////////////////////////////////////////////////////////////////////////// +template +using DN_BinarySearchLessThanProc = bool(T const &lhs, T const &rhs); + +template +bool DN_BinarySearch_DefaultLessThan(T const &lhs, T const &rhs); + +enum DN_BinarySearchType +{ + // Index of the match. If no match is found, found is set to false and the + // index is set to the index where the match should be inserted/exist, if + // it were in the array + DN_BinarySearchType_Match, + + // Index of the first element in the array that is `element >= find`. If no such + // item is found or the array is empty, then, the index is set to the array + // size and found is set to `false`. + // + // For example: + // int array[] = {0, 1, 2, 3, 4, 5}; + // DN_BinarySearchResult result = DN_BinarySearch(array, DN_ArrayCountU(array), 4, DN_BinarySearchType_LowerBound); + // printf("%zu\n", result.index); // Prints index '4' + + DN_BinarySearchType_LowerBound, + + // Index of the first element in the array that is `element > find`. If no such + // item is found or the array is empty, then, the index is set to the array + // size and found is set to `false`. + // + // For example: + // int array[] = {0, 1, 2, 3, 4, 5}; + // DN_BinarySearchResult result = DN_BinarySearch(array, DN_ArrayCountU(array), 4, DN_BinarySearchType_UpperBound); + // printf("%zu\n", result.index); // Prints index '5' + + DN_BinarySearchType_UpperBound, +}; + +struct DN_BinarySearchResult +{ + bool found; + DN_USize index; +}; + +template +using DN_QSortLessThanProc = bool(T const &a, T const &b, void *user_context); + +// NOTE: DN_PCG32 ////////////////////////////////////////////////////////////////////////////////// +DN_API DN_PCG32 DN_PCG32_Init (uint64_t seed); +DN_API uint32_t DN_PCG32_Next (DN_PCG32 *rng); +DN_API uint64_t DN_PCG32_Next64 (DN_PCG32 *rng); +DN_API uint32_t DN_PCG32_Range (DN_PCG32 *rng, uint32_t low, uint32_t high); +DN_API DN_F32 DN_PCG32_NextF32 (DN_PCG32 *rng); +DN_API DN_F64 DN_PCG32_NextF64 (DN_PCG32 *rng); +DN_API void DN_PCG32_Advance (DN_PCG32 *rng, uint64_t delta); + +#if !defined(DN_NO_JSON_BUILDER) +// NOTE: DN_JSONBuilder //////////////////////////////////////////////////////////////////////////// +#define DN_JSONBuilder_Object(builder) \ + DN_DeferLoop(DN_JSONBuilder_ObjectBegin(builder), \ + DN_JSONBuilder_ObjectEnd(builder)) + +#define DN_JSONBuilder_ObjectNamed(builder, name) \ + DN_DeferLoop(DN_JSONBuilder_ObjectBeginNamed(builder, name), \ + DN_JSONBuilder_ObjectEnd(builder)) + +#define DN_JSONBuilder_Array(builder) \ + DN_DeferLoop(DN_JSONBuilder_ArrayBegin(builder), \ + DN_JSONBuilder_ArrayEnd(builder)) + +#define DN_JSONBuilder_ArrayNamed(builder, name) \ + DN_DeferLoop(DN_JSONBuilder_ArrayBeginNamed(builder, name), \ + DN_JSONBuilder_ArrayEnd(builder)) + +DN_API DN_JSONBuilder DN_JSONBuilder_Init (DN_Arena *arena, int spaces_per_indent); +DN_API DN_Str8 DN_JSONBuilder_Build (DN_JSONBuilder const *builder, DN_Arena *arena); +DN_API void DN_JSONBuilder_KeyValue (DN_JSONBuilder *builder, DN_Str8 key, DN_Str8 value); +DN_API void DN_JSONBuilder_KeyValueF (DN_JSONBuilder *builder, DN_Str8 key, char const *value_fmt, ...); +DN_API void DN_JSONBuilder_ObjectBeginNamed (DN_JSONBuilder *builder, DN_Str8 name); +DN_API void DN_JSONBuilder_ObjectEnd (DN_JSONBuilder *builder); +DN_API void DN_JSONBuilder_ArrayBeginNamed (DN_JSONBuilder *builder, DN_Str8 name); +DN_API void DN_JSONBuilder_ArrayEnd (DN_JSONBuilder *builder); +DN_API void DN_JSONBuilder_Str8Named (DN_JSONBuilder *builder, DN_Str8 key, DN_Str8 value); +DN_API void DN_JSONBuilder_LiteralNamed (DN_JSONBuilder *builder, DN_Str8 key, DN_Str8 value); +DN_API void DN_JSONBuilder_U64Named (DN_JSONBuilder *builder, DN_Str8 key, uint64_t value); +DN_API void DN_JSONBuilder_I64Named (DN_JSONBuilder *builder, DN_Str8 key, int64_t value); +DN_API void DN_JSONBuilder_F64Named (DN_JSONBuilder *builder, DN_Str8 key, double value, int decimal_places); +DN_API void DN_JSONBuilder_BoolNamed (DN_JSONBuilder *builder, DN_Str8 key, bool value); + +#define DN_JSONBuilder_ObjectBegin(builder) DN_JSONBuilder_ObjectBeginNamed(builder, DN_Str8Lit("")) +#define DN_JSONBuilder_ArrayBegin(builder) DN_JSONBuilder_ArrayBeginNamed(builder, DN_Str8Lit("")) +#define DN_JSONBuilder_Str8(builder, value) DN_JSONBuilder_Str8Named(builder, DN_Str8Lit(""), value) +#define DN_JSONBuilder_Literal(builder, value) DN_JSONBuilder_LiteralNamed(builder, DN_Str8Lit(""), value) +#define DN_JSONBuilder_U64(builder, value) DN_JSONBuilder_U64Named(builder, DN_Str8Lit(""), value) +#define DN_JSONBuilder_I64(builder, value) DN_JSONBuilder_I64Named(builder, DN_Str8Lit(""), value) +#define DN_JSONBuilder_F64(builder, value) DN_JSONBuilder_F64Named(builder, DN_Str8Lit(""), value) +#define DN_JSONBuilder_Bool(builder, value) DN_JSONBuilder_BoolNamed(builder, DN_Str8Lit(""), value) +#endif // !defined(DN_NO_JSON_BUILDER) + +// NOTE: DN_BinarySearch +template bool DN_BinarySearch_DefaultLessThan(T const &lhs, T const &rhs); +template DN_BinarySearchResult DN_BinarySearch (T const *array, DN_USize array_size, T const &find, DN_BinarySearchType type = DN_BinarySearchType_Match, DN_BinarySearchLessThanProc less_than = DN_BinarySearch_DefaultLessThan); + +// NOTE: DN_QSort +template bool DN_QSort_DefaultLessThan(T const &lhs, T const &rhs, void *user_context); +template void DN_QSort (T *array, DN_USize array_size, void *user_context, DN_QSortLessThanProc less_than = DN_QSort_DefaultLessThan); + +// NOTE: DN_BinarySearch +template +bool DN_BinarySearch_DefaultLessThan(T const &lhs, T const &rhs) +{ + bool result = lhs < rhs; + return result; +} + +template +DN_BinarySearchResult DN_BinarySearch(T const *array, + DN_USize array_size, + T const &find, + DN_BinarySearchType type, + DN_BinarySearchLessThanProc less_than) +{ + DN_BinarySearchResult result = {}; + if (!array || array_size <= 0 || !less_than) + return result; + + T const *end = array + array_size; + T const *first = array; + T const *last = end; + while (first != last) { + DN_USize count = last - first; + T const *it = first + (count / 2); + + bool advance_first = false; + if (type == DN_BinarySearchType_UpperBound) + advance_first = !less_than(find, it[0]); + else + advance_first = less_than(it[0], find); + + if (advance_first) + first = it + 1; + else + last = it; + } + + switch (type) { + case DN_BinarySearchType_Match: { + result.found = first != end && !less_than(find, *first); + } break; + + case DN_BinarySearchType_LowerBound: /*FALLTHRU*/ + case DN_BinarySearchType_UpperBound: { + result.found = first != end; + } break; + } + + result.index = first - array; + return result; +} + +// NOTE: DN_QSort ////////////////////////////////////////////////////////////////////////////////// +template +bool DN_QSort_DefaultLessThan(T const &lhs, T const &rhs, void *user_context) +{ + (void)user_context; + bool result = lhs < rhs; + return result; +} + +template +void DN_QSort(T *array, DN_USize array_size, void *user_context, DN_QSortLessThanProc less_than) +{ + if (!array || array_size <= 1 || !less_than) + return; + + // NOTE: Insertion Sort, under 24->32 is an optimal amount ///////////////////////////////////// + const DN_USize QSORT_THRESHOLD = 24; + if (array_size < QSORT_THRESHOLD) { + for (DN_USize item_to_insert_index = 1; item_to_insert_index < array_size; item_to_insert_index++) { + for (DN_USize index = 0; index < item_to_insert_index; index++) { + if (!less_than(array[index], array[item_to_insert_index], user_context)) { + T item_to_insert = array[item_to_insert_index]; + for (DN_USize i = item_to_insert_index; i > index; i--) + array[i] = array[i - 1]; + + array[index] = item_to_insert; + break; + } + } + } + return; + } + + // NOTE: Quick sort, under 24->32 is an optimal amount ///////////////////////////////////////// + DN_USize last_index = array_size - 1; + DN_USize pivot_index = array_size / 2; + DN_USize partition_index = 0; + DN_USize start_index = 0; + + // Swap pivot with last index, so pivot is always at the end of the array. + // This makes logic much simpler. + DN_Swap(array[last_index], array[pivot_index]); + pivot_index = last_index; + + // 4^, 8, 7, 5, 2, 3, 6 + if (less_than(array[start_index], array[pivot_index], user_context)) + partition_index++; + start_index++; + + // 4, |8, 7, 5^, 2, 3, 6* + // 4, 5, |7, 8, 2^, 3, 6* + // 4, 5, 2, |8, 7, ^3, 6* + // 4, 5, 2, 3, |7, 8, ^6* + for (DN_USize index = start_index; index < last_index; index++) { + if (less_than(array[index], array[pivot_index], user_context)) { + DN_Swap(array[partition_index], array[index]); + partition_index++; + } + } + + // Move pivot to right of partition + // 4, 5, 2, 3, |6, 8, ^7* + DN_Swap(array[partition_index], array[pivot_index]); + DN_QSort(array, partition_index, user_context, less_than); + + // Skip the value at partion index since that is guaranteed to be sorted. + // 4, 5, 2, 3, (x), 8, 7 + DN_USize one_after_partition_index = partition_index + 1; + DN_QSort(array + one_after_partition_index, (array_size - one_after_partition_index), user_context, less_than); +} + +#endif // !defined(DN_HELPERS_H) +#endif + /* //////////////////////////////////////////////////////////////////////////////////////////////////// // diff --git a/Single-Header/dn_single_header.h b/Single-Header/dn_single_header.h index 4d248a9..49bb169 100644 --- a/Single-Header/dn_single_header.h +++ b/Single-Header/dn_single_header.h @@ -1,4 +1,4 @@ -// Generated by the DN single header generator 2025-11-09 17:09:52 +// Generated by the DN single header generator 2025-11-16 21:35:27 #if !defined(DN_BASE_INC_H) #define DN_BASE_INC_H @@ -58,7 +58,7 @@ #if !defined(DN_BASE_COMPILER_H) #define DN_BASE_COMPILER_H -// NOTE: Compiler identification /////////////////////////////////////////////////////////////////// +// NOTE: Compiler identification // Warning! Order is important here, clang-cl on Windows defines _MSC_VER #if defined(_MSC_VER) #if defined(__clang__) @@ -73,7 +73,7 @@ #define DN_COMPILER_GCC #endif -// NOTE: __has_feature ///////////////////////////////////////////////////////////////////////////// +// NOTE: __has_feature // MSVC for example does not support the feature detection macro for instance so we compile it out #if defined(__has_feature) #define DN_HAS_FEATURE(expr) __has_feature(expr) @@ -81,7 +81,7 @@ #define DN_HAS_FEATURE(expr) 0 #endif -// NOTE: __has_builtin ///////////////////////////////////////////////////////////////////////////// +// NOTE: __has_builtin // MSVC for example does not support the feature detection macro for instance so we compile it out #if defined(__has_builtin) #define DN_HAS_BUILTIN(expr) __has_builtin(expr) @@ -89,7 +89,7 @@ #define DN_HAS_BUILTIN(expr) 0 #endif -// NOTE: Warning suppression macros //////////////////////////////////////////////////////////////// +// NOTE: Warning suppression macros #if defined(DN_COMPILER_MSVC) #define DN_MSVC_WARNING_PUSH __pragma(warning(push)) #define DN_MSVC_WARNING_DISABLE(...) __pragma(warning(disable :##__VA_ARGS__)) @@ -112,14 +112,14 @@ #define DN_GCC_WARNING_POP #endif -// NOTE: Host OS identification //////////////////////////////////////////////////////////////////// +// NOTE: Host OS identification #if defined(_WIN32) #define DN_OS_WIN32 #elif defined(__gnu_linux__) || defined(__linux__) #define DN_OS_UNIX #endif -// NOTE: Platform identification /////////////////////////////////////////////////////////////////// +// NOTE: Platform identification #if !defined(DN_PLATFORM_EMSCRIPTEN) && \ !defined(DN_PLATFORM_POSIX) && \ !defined(DN_PLATFORM_WIN32) @@ -134,7 +134,7 @@ #endif #endif -// NOTE: Windows crap ////////////////////////////////////////////////////////////////////////////// +// NOTE: Windows crap #if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) #if defined(_CRT_SECURE_NO_WARNINGS) #define DN_CRT_SECURE_NO_WARNINGS_PREVIOUSLY_DEFINED @@ -143,21 +143,21 @@ #endif #endif -// NOTE: Force Inline ////////////////////////////////////////////////////////////////////////////// +// NOTE: Force Inline #if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) #define DN_FORCE_INLINE __forceinline #else #define DN_FORCE_INLINE inline __attribute__((always_inline)) #endif -// NOTE: Function/Variable Annotations ///////////////////////////////////////////////////////////// +// NOTE: Function/Variable Annotations #if defined(DN_STATIC_API) #define DN_API static #else #define DN_API #endif -// NOTE: C/CPP Literals //////////////////////////////////////////////////////////////////////////// +// NOTE: C/CPP Literals // Declare struct literals that work in both C and C++ because the syntax is different between // languages. #if 0 @@ -171,14 +171,14 @@ #define DN_Literal(T) (T) #endif -// NOTE: Thread Locals ///////////////////////////////////////////////////////////////////////////// +// NOTE: Thread Locals #if defined(__cplusplus) #define DN_THREAD_LOCAL thread_local #else #define DN_THREAD_LOCAL _Thread_local #endif -// NOTE: C variadic argument annotations /////////////////////////////////////////////////////////// +// NOTE: C variadic argument annotations // TODO: Other compilers #if defined(DN_COMPILER_MSVC) #define DN_FMT_ATTRIB _Printf_format_string_ @@ -186,17 +186,17 @@ #define DN_FMT_ATTRIB #endif -// NOTE: Type Cast ///////////////////////////////////////////////////////////////////////////////// +// NOTE: Type Cast #define DN_Cast(val) (val) -// NOTE: Zero initialisation macro ///////////////////////////////////////////////////////////////// +// NOTE: Zero initialisation macro #if defined(__cplusplus) #define DN_ZeroInit {} #else #define DN_ZeroInit {0} #endif -// NOTE: Address sanitizer ///////////////////////////////////////////////////////////////////////// +// NOTE: Address sanitizer #if !defined(DN_ASAN_POISON) #define DN_ASAN_POISON 0 #endif @@ -219,7 +219,9 @@ #if !defined(DN_BASE_H) #define DN_BASE_H -// DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif // NOTE: Macros #define DN_Stringify(x) #x @@ -3151,9 +3153,13 @@ DN_API DN_Str8 DN_Str8FromFmtVArena (DN_Arena *arena, DN DN_API DN_Str8 DN_Str8FromFmtPool (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...); DN_API DN_Str8 DN_Str8FromByteCountType (DN_ByteCountType type); DN_API DN_Str8x32 DN_Str8x32FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x32 DN_Str8x32FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8x64 DN_Str8x64FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x64 DN_Str8x64FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8x128 DN_Str8x128FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x256 DN_Str8x256FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8x256 DN_Str8x256FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x256 DN_Str8x256FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8x32 DN_Str8x32FromU64 (DN_U64 val, char separator); DN_API bool DN_Str8IsAll (DN_Str8 string, DN_Str8IsAllType is_all); DN_API char * DN_Str8End (DN_Str8 string); @@ -3355,34 +3361,44 @@ DN_API void DN_StackTraceReloadSymbols (); } while (0) #define DN_HardAssert(expr) DN_HardAssertF(expr, "") +// NOTE: Our default assert requires stack traces which has a bit of a chicken-and-egg problem if +// we're trying to detect some code related to the DN startup sequence. If we try to assert before +// the OS layer is initialised stack-traces will try to use temporary memory which requires TLS to +// be setup which belongs to the OS. +// +// This causes recursion errors as they call into each other. We use RawAsserts for these kind of +// checks. #if defined(DN_NO_ASSERT) + #define DN_RawAssert(...) #define DN_Assert(...) #define DN_AssertOnce(...) #define DN_AssertF(...) #define DN_AssertFOnce(...) #else - #define DN_AssertF(expr, fmt, ...) \ - do { \ - if (!(expr)) { \ + #define DN_RawAssert(expr) do { if (!(expr)) DN_DebugBreak; } while (0) + + #define DN_AssertF(expr, fmt, ...) \ + do { \ + if (!(expr)) { \ DN_Str8 stack_trace_ = DN_StackTraceWalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \ - DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ - DN_Str8PrintFmt(stack_trace_), \ - ##__VA_ARGS__); \ - DN_DebugBreak; \ - } \ + DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ + DN_Str8PrintFmt(stack_trace_), \ + ##__VA_ARGS__); \ + DN_DebugBreak; \ + } \ } while (0) - #define DN_AssertFOnce(expr, fmt, ...) \ - do { \ - static bool once = true; \ - if (!(expr) && once) { \ - once = false; \ + #define DN_AssertFOnce(expr, fmt, ...) \ + do { \ + static bool once = true; \ + if (!(expr) && once) { \ + once = false; \ DN_Str8 stack_trace_ = DN_StackTraceWalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \ - DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ - DN_Str8PrintFmt(stack_trace_), \ - ##__VA_ARGS__); \ - DN_DebugBreak; \ - } \ + DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ + DN_Str8PrintFmt(stack_trace_), \ + ##__VA_ARGS__); \ + DN_DebugBreak; \ + } \ } while (0) #define DN_Assert(expr) DN_AssertF((expr), "") @@ -4032,6 +4048,10 @@ DN_API void DN_LeakDump_ (DN_LeakTracker *leak); #if !defined(DN_OS_WINDOWS_H) #define DN_OS_WINDOWS_H +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + #if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) #pragma comment(lib, "bcrypt") #pragma comment(lib, "winhttp") @@ -5370,6 +5390,1352 @@ DN_API void DN_LeakDump_ (DN_LeakTracker *leak); #if !defined(DN_OS_WIN32_H) #define DN_OS_WIN32_H +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" + // DN: Single header generator commented out this header => #include "dn_os_windows.h" +#if !defined(DN_OS_WINDOWS_H) +#define DN_OS_WINDOWS_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +#if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) + #pragma comment(lib, "bcrypt") + #pragma comment(lib, "winhttp") + #pragma comment(lib, "dbghelp") + #pragma comment(lib, "comdlg32") + #pragma comment(lib, "pathcch") + #pragma comment(lib, "Shell32") // ShellExecuteW + #pragma comment(lib, "shlwapi") +#endif + +#if defined(DN_NO_WINDOWS_H_REPLACEMENT_HEADER) || defined(_INC_WINDOWS) + #define WIN32_LEAN_AND_MEAN + #include // LONG + #include // DN_OS_SecureRNGBytes -> BCryptOpenAlgorithmProvider ... etc + #include // DN_Win_MakeProcessDPIAware -> SetProcessDpiAwareProc + #include // PathRelativePathTO + #include // PathCchCanonicalizeEx + #include // WinHttp* + #include // PROCESS_MEMORY_COUNTERS_EX2 + #include // OPENFILENAMEW + #include +#else + DN_MSVC_WARNING_PUSH + DN_MSVC_WARNING_DISABLE(4201) // warning C4201: nonstandard extension used: nameless struct/union + + // NOTE: basetsd.h ///////////////////////////////////////////////////////////////////////////// + typedef unsigned __int64 ULONG_PTR, *PULONG_PTR; + typedef unsigned __int64 UINT_PTR, *PUINT_PTR; + typedef ULONG_PTR SIZE_T, *PSIZE_T; + typedef __int64 LONG_PTR, *PLONG_PTR; + typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; + typedef unsigned __int64 ULONG64, *PULONG64; + typedef unsigned __int64 DWORD64, *PDWORD64; + + // NOTE: shared/minwindef.h //////////////////////////////////////////////////////////////////// + struct HINSTANCE__ { + int unused; + }; + typedef struct HINSTANCE__ *HINSTANCE; + + typedef unsigned long DWORD; + typedef int BOOL; + typedef int INT; + typedef unsigned long ULONG; + typedef unsigned int UINT; + typedef unsigned short WORD; + typedef unsigned char BYTE; + typedef unsigned char UCHAR; + typedef HINSTANCE HMODULE; /* HMODULEs can be used in place of HINSTANCEs */ + typedef void * HANDLE; + typedef HANDLE HLOCAL; + + typedef unsigned __int64 WPARAM; + typedef LONG_PTR LPARAM; + typedef LONG_PTR LRESULT; + + #define MAX_PATH 260 + + typedef struct _FILETIME { + DWORD dwLowDateTime; + DWORD dwHighDateTime; + } FILETIME, *PFILETIME, *LPFILETIME; + + // NOTE: shared/winerror.h ///////////////////////////////////////////////////////////////////// + // NOTE: GetModuleFileNameW + #define ERROR_INSUFFICIENT_BUFFER 122L // dderror + + // NOTE: um/winnls.h /////////////////////////////////////////////////////////////////////////// + // NOTE: MultiByteToWideChar + #define CP_UTF8 65001 // UTF-8 translation + + // NOTE: um/winnt.h //////////////////////////////////////////////////////////////////////////// + typedef void VOID; + typedef __int64 LONGLONG; + typedef unsigned __int64 ULONGLONG; + typedef void * HANDLE; + typedef char CHAR; + typedef short SHORT; + typedef long LONG; + typedef wchar_t WCHAR; // wc, 16-bit UNICODE character + typedef CHAR * NPSTR, *LPSTR, *PSTR; + typedef WCHAR * NWPSTR, *LPWSTR, *PWSTR; + typedef long HRESULT; + + // NOTE: VirtualAlloc: Allocation Type + #define MEM_RESERVE 0x00002000 + #define MEM_COMMIT 0x00001000 + #define MEM_DECOMMIT 0x00004000 + #define MEM_RELEASE 0x00008000 + + // NOTE: VirtualAlloc: Page Permissions + #define PAGE_NOACCESS 0x01 + #define PAGE_READONLY 0x02 + #define PAGE_READWRITE 0x04 + #define PAGE_GUARD 0x100 + + // NOTE: HeapAlloc + #define HEAP_ZERO_MEMORY 0x00000008 + #define HEAP_NO_SERIALIZE 0x00000001 + #define HEAP_GROWABLE 0x00000002 + #define HEAP_GENERATE_EXCEPTIONS 0x00000004 + #define HEAP_ZERO_MEMORY 0x00000008 + #define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010 + #define HEAP_TAIL_CHECKING_ENABLED 0x00000020 + #define HEAP_FREE_CHECKING_ENABLED 0x00000040 + #define HEAP_DISABLE_COALESCE_ON_FREE 0x00000080 + #define HEAP_CREATE_ALIGN_16 0x00010000 + #define HEAP_CREATE_ENABLE_TRACING 0x00020000 + #define HEAP_CREATE_ENABLE_EXECUTE 0x00040000 + #define HEAP_MAXIMUM_TAG 0x0FFF + #define HEAP_PSEUDO_TAG_FLAG 0x8000 + #define HEAP_TAG_SHIFT 18 + #define HEAP_CREATE_SEGMENT_HEAP 0x00000100 + #define HEAP_CREATE_HARDENED 0x00000200 + + // NOTE: FormatMessageA + #define MAKELANGID(p, s) ((((WORD )(s)) << 10) | (WORD )(p)) + #define LANG_NEUTRAL 0x00 + #define SUBLANG_DEFAULT 0x01 // user default + + // NOTE: CreateFile + #define GENERIC_READ (0x80000000L) + #define GENERIC_WRITE (0x40000000L) + #define GENERIC_EXECUTE (0x20000000L) + #define GENERIC_ALL (0x10000000L) + + #define FILE_APPEND_DATA (0x0004) // file + + // NOTE: CreateFile/FindFirstFile + #define FILE_SHARE_READ 0x00000001 + #define FILE_SHARE_WRITE 0x00000002 + #define FILE_SHARE_DELETE 0x00000004 + + #define FILE_ATTRIBUTE_READONLY 0x00000001 + #define FILE_ATTRIBUTE_HIDDEN 0x00000002 + #define FILE_ATTRIBUTE_SYSTEM 0x00000004 + #define FILE_ATTRIBUTE_DIRECTORY 0x00000010 + #define FILE_ATTRIBUTE_NORMAL 0x00000080 + + // NOTE: STACKFRAME64 + #define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8) + + // NOTE: WaitForSingleObject + #define WAIT_TIMEOUT 258L // dderror + #define STATUS_WAIT_0 ((DWORD )0x00000000L) + #define STATUS_ABANDONED_WAIT_0 ((DWORD )0x00000080L) + + #define S_OK ((HRESULT)0L) + #define S_FALSE ((HRESULT)1L) + + typedef union _ULARGE_INTEGER { + struct { + DWORD LowPart; + DWORD HighPart; + } DUMMYSTRUCTNAME; + struct { + DWORD LowPart; + DWORD HighPart; + } u; + ULONGLONG QuadPart; + } ULARGE_INTEGER; + + typedef union _LARGE_INTEGER { + struct { + DWORD LowPart; + LONG HighPart; + } DUMMYSTRUCTNAME; + struct { + DWORD LowPart; + LONG HighPart; + } u; + LONGLONG QuadPart; + } LARGE_INTEGER; + + typedef struct __declspec(align(16)) _M128A { + ULONGLONG Low; + LONGLONG High; + } M128A, *PM128A; + + typedef struct __declspec(align(16)) _XSAVE_FORMAT { + WORD ControlWord; + WORD StatusWord; + BYTE TagWord; + BYTE Reserved1; + WORD ErrorOpcode; + DWORD ErrorOffset; + WORD ErrorSelector; + WORD Reserved2; + DWORD DataOffset; + WORD DataSelector; + WORD Reserved3; + DWORD MxCsr; + DWORD MxCsr_Mask; + M128A FloatRegisters[8]; + #if defined(_WIN64) + M128A XmmRegisters[16]; + BYTE Reserved4[96]; + #else + M128A XmmRegisters[8]; + BYTE Reserved4[224]; + #endif + } XSAVE_FORMAT, *PXSAVE_FORMAT; + typedef XSAVE_FORMAT XMM_SAVE_AREA32, *PXMM_SAVE_AREA32; + + typedef struct __declspec(align(16)) _CONTEXT { + DWORD64 P1Home; + DWORD64 P2Home; + DWORD64 P3Home; + DWORD64 P4Home; + DWORD64 P5Home; + DWORD64 P6Home; + DWORD ContextFlags; + DWORD MxCsr; + WORD SegCs; + WORD SegDs; + WORD SegEs; + WORD SegFs; + WORD SegGs; + WORD SegSs; + DWORD EFlags; + DWORD64 Dr0; + DWORD64 Dr1; + DWORD64 Dr2; + DWORD64 Dr3; + DWORD64 Dr6; + DWORD64 Dr7; + DWORD64 Rax; + DWORD64 Rcx; + DWORD64 Rdx; + DWORD64 Rbx; + DWORD64 Rsp; + DWORD64 Rbp; + DWORD64 Rsi; + DWORD64 Rdi; + DWORD64 R8; + DWORD64 R9; + DWORD64 R10; + DWORD64 R11; + DWORD64 R12; + DWORD64 R13; + DWORD64 R14; + DWORD64 R15; + DWORD64 Rip; + + union { + XMM_SAVE_AREA32 FltSave; + + struct { + M128A Header[2]; + M128A Legacy[8]; + M128A Xmm0; + M128A Xmm1; + M128A Xmm2; + M128A Xmm3; + M128A Xmm4; + M128A Xmm5; + M128A Xmm6; + M128A Xmm7; + M128A Xmm8; + M128A Xmm9; + M128A Xmm10; + M128A Xmm11; + M128A Xmm12; + M128A Xmm13; + M128A Xmm14; + M128A Xmm15; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + + M128A VectorRegister[26]; + DWORD64 VectorControl; + DWORD64 DebugControl; + DWORD64 LastBranchToRip; + DWORD64 LastBranchFromRip; + DWORD64 LastExceptionToRip; + DWORD64 LastExceptionFromRip; + } CONTEXT; + + typedef struct _LIST_ENTRY { + struct _LIST_ENTRY *Flink; + struct _LIST_ENTRY *Blink; + } LIST_ENTRY, *PLIST_ENTRY, PRLIST_ENTRY; + + typedef struct _RTL_CRITICAL_SECTION_DEBUG { + WORD Type; + WORD CreatorBackTraceIndex; + struct _RTL_CRITICAL_SECTION *CriticalSection; + LIST_ENTRY ProcessLocksList; + DWORD EntryCount; + DWORD ContentionCount; + DWORD Flags; + WORD CreatorBackTraceIndexHigh; + WORD Identifier; + } RTL_CRITICAL_SECTION_DEBUG, *PRTL_CRITICAL_SECTION_DEBUG, RTL_RESOURCE_DEBUG, *PRTL_RESOURCE_DEBUG; + + typedef struct _RTL_CONDITION_VARIABLE { + VOID *Ptr; + } RTL_CONDITION_VARIABLE, *PRTL_CONDITION_VARIABLE; + + #pragma pack(push, 8) + typedef struct _RTL_CRITICAL_SECTION { + PRTL_CRITICAL_SECTION_DEBUG DebugInfo; + + // + // The following three fields control entering and exiting the critical + // section for the resource + // + + LONG LockCount; + LONG RecursionCount; + HANDLE OwningThread; // from the thread's ClientId->UniqueThread + HANDLE LockSemaphore; + ULONG_PTR SpinCount; // force size on 64-bit systems when packed + } RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION; + #pragma pack(pop) + + typedef struct _MODLOAD_DATA { + DWORD ssize; // size of this struct + DWORD ssig; // signature identifying the passed data + VOID *data; // pointer to passed data + DWORD size; // size of passed data + DWORD flags; // options + } MODLOAD_DATA, *PMODLOAD_DATA; + + #define SLMFLAG_VIRTUAL 0x1 + #define SLMFLAG_ALT_INDEX 0x2 + #define SLMFLAG_NO_SYMBOLS 0x4 + + extern "C" + { + __declspec(dllimport) VOID __stdcall RtlCaptureContext(CONTEXT *ContextRecord); + __declspec(dllimport) HANDLE __stdcall GetCurrentProcess(void); + __declspec(dllimport) HANDLE __stdcall GetCurrentThread(void); + __declspec(dllimport) DWORD __stdcall SymSetOptions(DWORD SymOptions); + __declspec(dllimport) BOOL __stdcall SymInitialize(HANDLE hProcess, const CHAR* UserSearchPath, BOOL fInvadeProcess); + __declspec(dllimport) DWORD64 __stdcall SymLoadModuleEx(HANDLE hProcess, HANDLE hFile, CHAR const *ImageName, CHAR const *ModuleName, DWORD64 BaseOfDll, DWORD DllSize, MODLOAD_DATA *Data, DWORD Flags); + __declspec(dllimport) BOOL __stdcall SymUnloadModule64(HANDLE hProcess, DWORD64 BaseOfDll); + } + + // NOTE: um/heapapi.h //////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) HANDLE __stdcall HeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize); + __declspec(dllimport) BOOL __stdcall HeapDestroy(HANDLE hHeap); + __declspec(dllimport) VOID * __stdcall HeapAlloc(HANDLE hHeap, DWORD dwFlags,SIZE_T dwBytes); + __declspec(dllimport) VOID * __stdcall HeapReAlloc(HANDLE hHeap, DWORD dwFlags, VOID *lpMem, SIZE_T dwBytes); + __declspec(dllimport) BOOL __stdcall HeapFree(HANDLE hHeap, DWORD dwFlags, VOID *lpMem); + __declspec(dllimport) SIZE_T __stdcall HeapSize(HANDLE hHeap, DWORD dwFlags, VOID const *lpMem); + __declspec(dllimport) HANDLE __stdcall GetProcessHeap(VOID); + __declspec(dllimport) SIZE_T __stdcall HeapCompact(HANDLE hHeap, DWORD dwFlags); + } + + // NOTE: shared/windef.h //////////////////////////////////////////////////////////////////// + typedef struct tagPOINT + { + LONG x; + LONG y; + } POINT, *PPOINT, *NPPOINT, *LPPOINT; + + // NOTE: handleapi.h /////////////////////////////////////////////////////////////////////////// + #define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1) + + extern "C" + { + __declspec(dllimport) BOOL __stdcall CloseHandle(HANDLE hObject); + } + + // NOTE: consoleapi.h /////////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall WriteConsoleA(HANDLE hConsoleOutput, const VOID* lpBuffer, DWORD nNumberOfCharsToWrite, DWORD *lpNumberOfCharsWritten, VOID *lpReserved); + __declspec(dllimport) BOOL __stdcall AllocConsole(VOID); + __declspec(dllimport) BOOL __stdcall FreeConsole(VOID); + __declspec(dllimport) BOOL __stdcall AttachConsole(DWORD dwProcessId); + __declspec(dllimport) BOOL __stdcall GetConsoleMode(HANDLE hConsoleHandle, DWORD *lpMode); + } + + // NOTE: um/minwinbase.h /////////////////////////////////////////////////////////////////////// + // NOTE: FindFirstFile + #define FIND_FIRST_EX_CASE_SENSITIVE 0x00000001 + #define FIND_FIRST_EX_LARGE_FETCH 0x00000002 + + // NOTE: WaitFor.. + #define WAIT_FAILED ((DWORD)0xFFFFFFFF) + #define WAIT_OBJECT_0 ((STATUS_WAIT_0 ) + 0 ) + #define WAIT_ABANDONED ((STATUS_ABANDONED_WAIT_0 ) + 0 ) + #define WAIT_ABANDONED_0 ((STATUS_ABANDONED_WAIT_0 ) + 0 ) + + // NOTE: CreateProcessW + #define CREATE_UNICODE_ENVIRONMENT 0x00000400 + #define CREATE_NO_WINDOW 0x08000000 + + typedef enum _GET_FILEEX_INFO_LEVELS { + GetFileExInfoStandard, + GetFileExMaxInfoLevel + } GET_FILEEX_INFO_LEVELS; + + typedef struct _SECURITY_ATTRIBUTES { + DWORD nLength; + VOID *lpSecurityDescriptor; + BOOL bInheritHandle; + } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; + + typedef enum _FINDEX_INFO_LEVELS { + FindExInfoStandard, + FindExInfoBasic, + FindExInfoMaxInfoLevel + } FINDEX_INFO_LEVELS; + + typedef enum _FINDEX_SEARCH_OPS { + FindExSearchNameMatch, + FindExSearchLimitToDirectories, + FindExSearchLimitToDevices, + FindExSearchMaxSearchOp + } FINDEX_SEARCH_OPS; + + typedef struct _WIN32_FIND_DATAW { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwReserved0; + DWORD dwReserved1; + WCHAR cFileName[ MAX_PATH ]; + WCHAR cAlternateFileName[ 14 ]; + #ifdef _MAC + DWORD dwFileType; + DWORD dwCreatorType; + WORD wFinderFlags; + #endif + } WIN32_FIND_DATAW, *PWIN32_FIND_DATAW, *LPWIN32_FIND_DATAW; + + typedef struct _SYSTEMTIME { + WORD wYear; + WORD wMonth; + WORD wDayOfWeek; + WORD wDay; + WORD wHour; + WORD wMinute; + WORD wSecond; + WORD wMilliseconds; + } SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME; + + typedef struct _OVERLAPPED { + ULONG_PTR Internal; + ULONG_PTR InternalHigh; + union { + struct { + DWORD Offset; + DWORD OffsetHigh; + } DUMMYSTRUCTNAME; + VOID *Pointer; + } DUMMYUNIONNAME; + + HANDLE hEvent; + } OVERLAPPED, *LPOVERLAPPED; + + typedef RTL_CRITICAL_SECTION CRITICAL_SECTION; + + #define WAIT_FAILED ((DWORD)0xFFFFFFFF) + #define WAIT_OBJECT_0 ((STATUS_WAIT_0 ) + 0 ) + + #define INFINITE 0xFFFFFFFF // Wait/Synchronisation: Infinite timeout + + #define STD_INPUT_HANDLE ((DWORD)-10) + #define STD_OUTPUT_HANDLE ((DWORD)-11) + #define STD_ERROR_HANDLE ((DWORD)-12) + + #define HANDLE_FLAG_INHERIT 0x00000001 + #define HANDLE_FLAG_PROTECT_FROM_CLOSE 0x00000002 + + // NOTE: MoveFile + #define MOVEFILE_REPLACE_EXISTING 0x00000001 + #define MOVEFILE_COPY_ALLOWED 0x00000002 + + // NOTE: FormatMessageA + #define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100 + #define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200 + #define FORMAT_MESSAGE_FROM_HMODULE 0x00000800 + #define FORMAT_MESSAGE_FROM_SYSTEM 0x00001000 + + // NOTE: CreateProcessW + #define STARTF_USESTDHANDLES 0x00000100 + + extern "C" + { + __declspec(dllimport) BOOL __stdcall MoveFileExW (const WCHAR *lpExistingFileName, const WCHAR *lpNewFileName, DWORD dwFlags); + __declspec(dllimport) BOOL __stdcall CopyFileW (const WCHAR *lpExistingFileName, const WCHAR *lpNewFileName, BOOL bFailIfExists); + __declspec(dllimport) HANDLE __stdcall CreateSemaphoreA(SECURITY_ATTRIBUTES *lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, const CHAR *lpName); + __declspec(dllimport) DWORD __stdcall FormatMessageW (DWORD dwFlags, VOID const *lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, va_list *Arguments); + __declspec(dllimport) HLOCAL __stdcall LocalFree (HLOCAL hMem); + } + + // NOTE: um/stringapiset.h ///////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) int __stdcall MultiByteToWideChar(UINT CodePage, DWORD dwFlags, const CHAR *lpMultiByteStr, int cbMultiByte, WCHAR *lpWideCharStr, int cchWideChar); + __declspec(dllimport) int __stdcall WideCharToMultiByte(UINT CodePage, DWORD dwFlags, const WCHAR *lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, const CHAR *lpDefaultChar, BOOL *lpUsedDefaultChar); + } + + // NOTE: um/fileapi.h ////////////////////////////////////////////////////////////////////////// + #define INVALID_FILE_SIZE ((DWORD)0xFFFFFFFF) + #define INVALID_FILE_ATTRIBUTES ((DWORD)-1) + + // NOTE: CreateFile + #define CREATE_NEW 1 + #define CREATE_ALWAYS 2 + #define OPEN_EXISTING 3 + #define OPEN_ALWAYS 4 + #define TRUNCATE_EXISTING 5 + + typedef struct _WIN32_FILE_ATTRIBUTE_DATA { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + } WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall FlushFileBuffers (HANDLE hFile); + __declspec(dllimport) BOOL __stdcall CreateDirectoryW (const WCHAR *lpPathName, SECURITY_ATTRIBUTES *lpSecurityAttributes); + __declspec(dllimport) BOOL __stdcall RemoveDirectoryW (const WCHAR *lpPathName); + __declspec(dllimport) BOOL __stdcall FindNextFileW (HANDLE hFindFile, WIN32_FIND_DATAW *lpFindFileData); + __declspec(dllimport) BOOL __stdcall FindClose (HANDLE hFindFile); + + __declspec(dllimport) HANDLE __stdcall FindFirstFileExW (const WCHAR *lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, VOID *lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, VOID *lpSearchFilter, DWORD dwAdditionalFlags); + __declspec(dllimport) BOOL __stdcall GetFileAttributesExW(const WCHAR *lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, VOID *lpFileInformation); + __declspec(dllimport) BOOL __stdcall GetFileSizeEx (HANDLE hFile, LARGE_INTEGER *lpFileSize); + __declspec(dllimport) BOOL __stdcall DeleteFileW (const WCHAR *lpFileName); + __declspec(dllimport) HANDLE __stdcall CreateFileW (const WCHAR *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, SECURITY_ATTRIBUTES *lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); + __declspec(dllimport) BOOL __stdcall ReadFile (HANDLE hFile, VOID *lpBuffer, DWORD nNumberOfBytesToRead, DWORD *lpNumberOfBytesRead, OVERLAPPED *lpOverlapped); + __declspec(dllimport) BOOL __stdcall WriteFile (HANDLE hFile, const VOID *lpBuffer, DWORD nNumberOfBytesToWrite, DWORD *lpNumberOfBytesWritten, OVERLAPPED *lpOverlapped); + __declspec(dllimport) BOOL __stdcall GetDiskFreeSpaceExW (WCHAR const *lpDirectoryName, ULARGE_INTEGER *lpFreeBytesAvailableToCaller, ULARGE_INTEGER *lpTotalNumberOfBytes, ULARGE_INTEGER *lpTotalNumberOfFreeBytes); + } + + // NOTE: um/processenv.h /////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) DWORD __stdcall GetCurrentDirectoryW (DWORD nBufferLength, WCHAR *lpBuffer); + __declspec(dllimport) HANDLE __stdcall GetStdHandle (DWORD nStdHandle); + __declspec(dllimport) WCHAR* __stdcall GetEnvironmentStringsW (); + __declspec(dllimport) BOOL __stdcall FreeEnvironmentStringsW(WCHAR *penv); + __declspec(dllimport) DWORD __stdcall GetEnvironmentVariableW(WCHAR const *lpName, WCHAR *lpBuffer, DWORD nSize); + __declspec(dllimport) BOOL __stdcall SetEnvironmentVariableW(WCHAR const *lpName, WCHAR const *lpValue); + } + + // NOTE: um/psapi.h //////////////////////////////////////////////////////////////////////////// + typedef struct _PROCESS_MEMORY_COUNTERS { + DWORD cb; + DWORD PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; + } PROCESS_MEMORY_COUNTERS; + typedef PROCESS_MEMORY_COUNTERS *PPROCESS_MEMORY_COUNTERS; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall GetProcessMemoryInfo(HANDLE Process, PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb); + } + + // NOTE: um/sysinfoapi.h /////////////////////////////////////////////////////////////////////// + typedef struct _SYSTEM_INFO { + union { + DWORD dwOemId; // Obsolete field...do not use + struct { + WORD wProcessorArchitecture; + WORD wReserved; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + DWORD dwPageSize; + VOID *lpMinimumApplicationAddress; + VOID *lpMaximumApplicationAddress; + DWORD_PTR dwActiveProcessorMask; + DWORD dwNumberOfProcessors; + DWORD dwProcessorType; + DWORD dwAllocationGranularity; + WORD wProcessorLevel; + WORD wProcessorRevision; + } SYSTEM_INFO, *LPSYSTEM_INFO; + + extern "C" + { + __declspec(dllimport) VOID __stdcall GetSystemInfo(SYSTEM_INFO *lpSystemInfo); + __declspec(dllimport) VOID __stdcall GetSystemTime(SYSTEMTIME *lpSystemTime); + __declspec(dllimport) VOID __stdcall GetSystemTimeAsFileTime(FILETIME *lpSystemTimeAsFileTime); + __declspec(dllimport) VOID __stdcall GetLocalTime(SYSTEMTIME *lpSystemTime); + } + + // NOTE: um/timezoneapi.h ////////////////////////////////////////////////////////////////////// + typedef struct _TIME_ZONE_INFORMATION { + LONG Bias; + WCHAR StandardName[32]; + SYSTEMTIME StandardDate; + LONG StandardBias; + WCHAR DaylightName[32]; + SYSTEMTIME DaylightDate; + LONG DaylightBias; + } TIME_ZONE_INFORMATION, *PTIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall FileTimeToSystemTime (const FILETIME* lpFileTime, SYSTEMTIME *lpSystemTime); + __declspec(dllimport) BOOL __stdcall SystemTimeToFileTime (const SYSTEMTIME* lpSystemTime, FILETIME *lpFileTime); + __declspec(dllimport) BOOL __stdcall TzSpecificLocalTimeToSystemTime(const TIME_ZONE_INFORMATION* lpTimeZoneInformation, const SYSTEMTIME* lpLocalTime, const LPSYSTEMTIME lpUniversalTime); + } + + // NOTE: shared/windef.h /////////////////////////////////////////////////////////////////////// + typedef struct tagRECT { + LONG left; + LONG top; + LONG right; + LONG bottom; + } RECT; + + struct HWND__ { + int unused; + }; + typedef struct HWND__ *HWND; + + struct DPI_AWARENESS_CONTEXT__ { + int unused; + }; + typedef struct DPI_AWARENESS_CONTEXT__ *DPI_AWARENESS_CONTEXT; + + typedef enum DPI_AWARENESS { + DPI_AWARENESS_INVALID = -1, + DPI_AWARENESS_UNAWARE = 0, + DPI_AWARENESS_SYSTEM_AWARE = 1, + DPI_AWARENESS_PER_MONITOR_AWARE = 2 + } DPI_AWARENESS; + + #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4) + + // NOTE: um/winuser.h ////////////////////////////////////////////////////////////////////////// + typedef struct tagWINDOWPLACEMENT { + UINT length; + UINT flags; + UINT showCmd; + POINT ptMinPosition; + POINT ptMaxPosition; + RECT rcNormalPosition; + #ifdef _MAC + RECT rcDevice; + #endif + } WINDOWPLACEMENT; + typedef WINDOWPLACEMENT *PWINDOWPLACEMENT, *LPWINDOWPLACEMENT; + + #define SW_HIDE 0 + #define SW_NORMAL 1 + #define SW_MAXIMIZE 3 + #define SW_SHOWNOACTIVATE 4 + #define SW_SHOW 5 + #define SW_FORCEMINIMIZE 11 + + extern "C" + { + __declspec(dllimport) BOOL __stdcall GetWindowRect (HWND hWnd, RECT *lpRect); + __declspec(dllimport) BOOL __stdcall SetWindowPos (HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags); + __declspec(dllimport) UINT __stdcall GetWindowModuleFileNameA(HWND hwnd, LPSTR pszFileName, UINT cchFileNameMax); + __declspec(dllimport) BOOL __stdcall ShowWindow (HWND hWnd, int nCmdShow); + __declspec(dllimport) BOOL __stdcall GetWindowPlacement (HWND hWnd, WINDOWPLACEMENT *lpwndpl); + + } + + // NOTE: um/wininet.h ////////////////////////////////////////////////////////////////////////// + typedef WORD INTERNET_PORT; + typedef VOID *HINTERNET; + + // NOTE: um/winhttp.h ////////////////////////////////////////////////////////////////////////// + #define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY 0 + #define WINHTTP_ACCESS_TYPE_NO_PROXY 1 + #define WINHTTP_ACCESS_TYPE_NAMED_PROXY 3 + #define WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY 4 + + #define INTERNET_DEFAULT_PORT 0 // use the protocol-specific default + #define INTERNET_DEFAULT_HTTP_PORT 80 // " " HTTP " + #define INTERNET_DEFAULT_HTTPS_PORT 443 // " " HTTPS " + + // NOTE: WinHttpOpen + #define WINHTTP_FLAG_ASYNC 0x10000000 // this session is asynchronous (where supported) + #define WINHTTP_FLAG_SECURE_DEFAULTS 0x30000000 // note that this flag also forces async + + // NOTE: WinHttpOpenRequest + #define WINHTTP_FLAG_SECURE 0x00800000 // use SSL if applicable (HTTPS) + #define WINHTTP_FLAG_ESCAPE_PERCENT 0x00000004 // if escaping enabled, escape percent as well + #define WINHTTP_FLAG_NULL_CODEPAGE 0x00000008 // assume all symbols are ASCII, use fast convertion + #define WINHTTP_FLAG_ESCAPE_DISABLE 0x00000040 // disable escaping + #define WINHTTP_FLAG_ESCAPE_DISABLE_QUERY 0x00000080 // if escaping enabled escape path part, but do not escape query + #define WINHTTP_FLAG_BYPASS_PROXY_CACHE 0x00000100 // add "pragma: no-cache" request header + #define WINHTTP_FLAG_REFRESH WINHTTP_FLAG_BYPASS_PROXY_CACHE + #define WINHTTP_FLAG_AUTOMATIC_CHUNKING 0x00000200 // Send request without content-length header or chunked TE + + #define WINHTTP_NO_PROXY_NAME NULL + #define WINHTTP_NO_PROXY_BYPASS NULL + + // + // WINHTTP_QUERY_FLAG_NUMBER - if this bit is set in the dwInfoLevel parameter of + // HttpQueryHeader(), then the value of the header will be converted to a number + // before being returned to the caller, if applicable + // + #define WINHTTP_QUERY_FLAG_NUMBER 0x20000000 + + #define WINHTTP_QUERY_MIME_VERSION 0 + #define WINHTTP_QUERY_CONTENT_TYPE 1 + #define WINHTTP_QUERY_CONTENT_TRANSFER_ENCODING 2 + #define WINHTTP_QUERY_CONTENT_ID 3 + #define WINHTTP_QUERY_CONTENT_DESCRIPTION 4 + #define WINHTTP_QUERY_CONTENT_LENGTH 5 + #define WINHTTP_QUERY_CONTENT_LANGUAGE 6 + #define WINHTTP_QUERY_ALLOW 7 + #define WINHTTP_QUERY_PUBLIC 8 + #define WINHTTP_QUERY_DATE 9 + #define WINHTTP_QUERY_EXPIRES 10 + #define WINHTTP_QUERY_LAST_MODIFIED 11 + #define WINHTTP_QUERY_MESSAGE_ID 12 + #define WINHTTP_QUERY_URI 13 + #define WINHTTP_QUERY_DERIVED_FROM 14 + #define WINHTTP_QUERY_COST 15 + #define WINHTTP_QUERY_LINK 16 + #define WINHTTP_QUERY_PRAGMA 17 + #define WINHTTP_QUERY_VERSION 18 // special: part of status line + #define WINHTTP_QUERY_STATUS_CODE 19 // special: part of status line + #define WINHTTP_QUERY_STATUS_TEXT 20 // special: part of status line + #define WINHTTP_QUERY_RAW_HEADERS 21 // special: all headers as ASCIIZ + #define WINHTTP_QUERY_RAW_HEADERS_CRLF 22 // special: all headers + #define WINHTTP_QUERY_CONNECTION 23 + #define WINHTTP_QUERY_ACCEPT 24 + #define WINHTTP_QUERY_ACCEPT_CHARSET 25 + #define WINHTTP_QUERY_ACCEPT_ENCODING 26 + #define WINHTTP_QUERY_ACCEPT_LANGUAGE 27 + #define WINHTTP_QUERY_AUTHORIZATION 28 + #define WINHTTP_QUERY_CONTENT_ENCODING 29 + #define WINHTTP_QUERY_FORWARDED 30 + #define WINHTTP_QUERY_FROM 31 + #define WINHTTP_QUERY_IF_MODIFIED_SINCE 32 + #define WINHTTP_QUERY_LOCATION 33 + #define WINHTTP_QUERY_ORIG_URI 34 + #define WINHTTP_QUERY_REFERER 35 + #define WINHTTP_QUERY_RETRY_AFTER 36 + #define WINHTTP_QUERY_SERVER 37 + #define WINHTTP_QUERY_TITLE 38 + #define WINHTTP_QUERY_USER_AGENT 39 + #define WINHTTP_QUERY_WWW_AUTHENTICATE 40 + #define WINHTTP_QUERY_PROXY_AUTHENTICATE 41 + #define WINHTTP_QUERY_ACCEPT_RANGES 42 + #define WINHTTP_QUERY_SET_COOKIE 43 + #define WINHTTP_QUERY_COOKIE 44 + #define WINHTTP_QUERY_REQUEST_METHOD 45 // special: GET/POST etc. + #define WINHTTP_QUERY_REFRESH 46 + #define WINHTTP_QUERY_CONTENT_DISPOSITION 47 + + // NOTE: WinHttpQueryHeaders prettifiers for optional parameters. + #define WINHTTP_HEADER_NAME_BY_INDEX NULL + #define WINHTTP_NO_OUTPUT_BUFFER NULL + #define WINHTTP_NO_HEADER_INDEX NULL + + // NOTE: Http Response Status Codes + #define HTTP_STATUS_CONTINUE 100 // OK to continue with request + #define HTTP_STATUS_SWITCH_PROTOCOLS 101 // server has switched protocols in upgrade header + + #define HTTP_STATUS_OK 200 // request completed + #define HTTP_STATUS_CREATED 201 // object created, reason = new URI + #define HTTP_STATUS_ACCEPTED 202 // async completion (TBS) + #define HTTP_STATUS_PARTIAL 203 // partial completion + #define HTTP_STATUS_NO_CONTENT 204 // no info to return + #define HTTP_STATUS_RESET_CONTENT 205 // request completed, but clear form + #define HTTP_STATUS_PARTIAL_CONTENT 206 // partial GET fulfilled + #define HTTP_STATUS_WEBDAV_MULTI_STATUS 207 // WebDAV Multi-Status + + #define HTTP_STATUS_AMBIGUOUS 300 // server couldn't decide what to return + #define HTTP_STATUS_MOVED 301 // object permanently moved + #define HTTP_STATUS_REDIRECT 302 // object temporarily moved + #define HTTP_STATUS_REDIRECT_METHOD 303 // redirection w/ new access method + #define HTTP_STATUS_NOT_MODIFIED 304 // if-modified-since was not modified + #define HTTP_STATUS_USE_PROXY 305 // redirection to proxy, location header specifies proxy to use + #define HTTP_STATUS_REDIRECT_KEEP_VERB 307 // HTTP/1.1: keep same verb + #define HTTP_STATUS_PERMANENT_REDIRECT 308 // Object permanently moved keep verb + + #define HTTP_STATUS_BAD_REQUEST 400 // invalid syntax + #define HTTP_STATUS_DENIED 401 // access denied + #define HTTP_STATUS_PAYMENT_REQ 402 // payment required + #define HTTP_STATUS_FORBIDDEN 403 // request forbidden + #define HTTP_STATUS_NOT_FOUND 404 // object not found + #define HTTP_STATUS_BAD_METHOD 405 // method is not allowed + #define HTTP_STATUS_NONE_ACCEPTABLE 406 // no response acceptable to client found + #define HTTP_STATUS_PROXY_AUTH_REQ 407 // proxy authentication required + #define HTTP_STATUS_REQUEST_TIMEOUT 408 // server timed out waiting for request + #define HTTP_STATUS_CONFLICT 409 // user should resubmit with more info + #define HTTP_STATUS_GONE 410 // the resource is no longer available + #define HTTP_STATUS_LENGTH_REQUIRED 411 // the server refused to accept request w/o a length + #define HTTP_STATUS_PRECOND_FAILED 412 // precondition given in request failed + #define HTTP_STATUS_REQUEST_TOO_LARGE 413 // request entity was too large + #define HTTP_STATUS_URI_TOO_LONG 414 // request URI too long + #define HTTP_STATUS_UNSUPPORTED_MEDIA 415 // unsupported media type + #define HTTP_STATUS_RETRY_WITH 449 // retry after doing the appropriate action. + + #define HTTP_STATUS_SERVER_ERROR 500 // internal server error + #define HTTP_STATUS_NOT_SUPPORTED 501 // required not supported + #define HTTP_STATUS_BAD_GATEWAY 502 // error response received from gateway + #define HTTP_STATUS_SERVICE_UNAVAIL 503 // temporarily overloaded + #define HTTP_STATUS_GATEWAY_TIMEOUT 504 // timed out waiting for gateway + #define HTTP_STATUS_VERSION_NOT_SUP 505 // HTTP version not supported + + #define HTTP_STATUS_FIRST HTTP_STATUS_CONTINUE + #define HTTP_STATUS_LAST HTTP_STATUS_VERSION_NOT_SUP + + #define WINHTTP_CALLBACK_STATUS_RESOLVING_NAME 0x00000001 + #define WINHTTP_CALLBACK_STATUS_NAME_RESOLVED 0x00000002 + #define WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER 0x00000004 + #define WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER 0x00000008 + #define WINHTTP_CALLBACK_STATUS_SENDING_REQUEST 0x00000010 + #define WINHTTP_CALLBACK_STATUS_REQUEST_SENT 0x00000020 + #define WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE 0x00000040 + #define WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED 0x00000080 + #define WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION 0x00000100 + #define WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED 0x00000200 + #define WINHTTP_CALLBACK_STATUS_HANDLE_CREATED 0x00000400 + #define WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING 0x00000800 + #define WINHTTP_CALLBACK_STATUS_DETECTING_PROXY 0x00001000 + #define WINHTTP_CALLBACK_STATUS_REDIRECT 0x00004000 + #define WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE 0x00008000 + #define WINHTTP_CALLBACK_STATUS_SECURE_FAILURE 0x00010000 + #define WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE 0x00020000 + #define WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE 0x00040000 + #define WINHTTP_CALLBACK_STATUS_READ_COMPLETE 0x00080000 + #define WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE 0x00100000 + #define WINHTTP_CALLBACK_STATUS_REQUEST_ERROR 0x00200000 + #define WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE 0x00400000 + + #define WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE 0x01000000 + #define WINHTTP_CALLBACK_STATUS_CLOSE_COMPLETE 0x02000000 + #define WINHTTP_CALLBACK_STATUS_SHUTDOWN_COMPLETE 0x04000000 + #define WINHTTP_CALLBACK_STATUS_SETTINGS_WRITE_COMPLETE 0x10000000 + #define WINHTTP_CALLBACK_STATUS_SETTINGS_READ_COMPLETE 0x20000000 + + #define WINHTTP_CALLBACK_FLAG_RESOLVE_NAME (WINHTTP_CALLBACK_STATUS_RESOLVING_NAME | WINHTTP_CALLBACK_STATUS_NAME_RESOLVED) + #define WINHTTP_CALLBACK_FLAG_CONNECT_TO_SERVER (WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER | WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER) + #define WINHTTP_CALLBACK_FLAG_SEND_REQUEST (WINHTTP_CALLBACK_STATUS_SENDING_REQUEST | WINHTTP_CALLBACK_STATUS_REQUEST_SENT) + #define WINHTTP_CALLBACK_FLAG_RECEIVE_RESPONSE (WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE | WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED) + #define WINHTTP_CALLBACK_FLAG_CLOSE_CONNECTION (WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION | WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED) + #define WINHTTP_CALLBACK_FLAG_HANDLES (WINHTTP_CALLBACK_STATUS_HANDLE_CREATED | WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING) + #define WINHTTP_CALLBACK_FLAG_DETECTING_PROXY WINHTTP_CALLBACK_STATUS_DETECTING_PROXY + #define WINHTTP_CALLBACK_FLAG_REDIRECT WINHTTP_CALLBACK_STATUS_REDIRECT + #define WINHTTP_CALLBACK_FLAG_INTERMEDIATE_RESPONSE WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE + #define WINHTTP_CALLBACK_FLAG_SECURE_FAILURE WINHTTP_CALLBACK_STATUS_SECURE_FAILURE + #define WINHTTP_CALLBACK_FLAG_SENDREQUEST_COMPLETE WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE + #define WINHTTP_CALLBACK_FLAG_HEADERS_AVAILABLE WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE + #define WINHTTP_CALLBACK_FLAG_DATA_AVAILABLE WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE + #define WINHTTP_CALLBACK_FLAG_READ_COMPLETE WINHTTP_CALLBACK_STATUS_READ_COMPLETE + #define WINHTTP_CALLBACK_FLAG_WRITE_COMPLETE WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE + #define WINHTTP_CALLBACK_FLAG_REQUEST_ERROR WINHTTP_CALLBACK_STATUS_REQUEST_ERROR + + #define WINHTTP_CALLBACK_FLAG_GETPROXYFORURL_COMPLETE WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE + + #define WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS (WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE \ + | WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE \ + | WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE \ + | WINHTTP_CALLBACK_STATUS_READ_COMPLETE \ + | WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE \ + | WINHTTP_CALLBACK_STATUS_REQUEST_ERROR \ + | WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE) + + #define WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS 0xffffffff + #define WINHTTP_INVALID_STATUS_CALLBACK ((WINHTTP_STATUS_CALLBACK)(-1L)) + + typedef struct _WINHTTP_EXTENDED_HEADER + { + union + { + CHAR const *pwszName; + WCHAR const *pszName; + }; + union + { + WCHAR const *pwszValue; + CHAR const *pszValue; + }; + } WINHTTP_EXTENDED_HEADER, *PWINHTTP_EXTENDED_HEADER; + + typedef struct _WINHTTP_ASYNC_RESULT + { + DWORD *dwResult; // indicates which async API has encountered an error + DWORD dwError; // the error code if the API failed + } WINHTTP_ASYNC_RESULT, *LPWINHTTP_ASYNC_RESULT, *PWINHTTP_ASYNC_RESULT; + + typedef + VOID + (*WINHTTP_STATUS_CALLBACK)( + HINTERNET hInternet, + DWORD *dwContext, + DWORD dwInternetStatus, + VOID *lpvStatusInformation, + DWORD dwStatusInformationLength + ); + + extern "C" + { + __declspec(dllimport) HINTERNET __stdcall WinHttpOpen(WCHAR const *pszAgentW, DWORD dwAccessType, WCHAR const *pszProxyW, WCHAR const *pszProxyBypassW, DWORD dwFlags); + __declspec(dllimport) BOOL __stdcall WinHttpCloseHandle(HINTERNET hInternet); + __declspec(dllimport) HINTERNET __stdcall WinHttpConnect(HINTERNET hSession, WCHAR const *pswzServerName, INTERNET_PORT nServerPort, DWORD dwReserved); + __declspec(dllimport) BOOL __stdcall WinHttpReadData(HINTERNET hRequest, VOID *lpBuffer, DWORD dwNumberOfBytesToRead, DWORD *lpdwNumberOfBytesRead); + __declspec(dllimport) HINTERNET __stdcall WinHttpOpenRequest(HINTERNET hConnect, WCHAR const *pwszVerb, WCHAR const *pwszObjectName, WCHAR const *pwszVersion, WCHAR const *pwszReferrer, WCHAR const *ppwszAcceptTypes, DWORD dwFlags); + __declspec(dllimport) BOOL __stdcall WinHttpSendRequest(HINTERNET hRequest, WCHAR const *lpszHeaders, DWORD dwHeadersLength, VOID *lpOptional, DWORD dwOptionalLength, DWORD dwTotalLength, DWORD_PTR dwContext); + __declspec(dllimport) DWORD __stdcall WinHttpAddRequestHeadersEx(HINTERNET hRequest, DWORD dwModifiers, ULONGLONG ullFlags, ULONGLONG ullExtra, DWORD cHeaders, WINHTTP_EXTENDED_HEADER *pHeaders); + __declspec(dllimport) BOOL __stdcall WinHttpSetCredentials(HINTERNET hRequest, // HINTERNET handle returned by WinHttpOpenRequest. + DWORD AuthTargets, // Only WINHTTP_AUTH_TARGET_SERVER and WINHTTP_AUTH_TARGET_PROXY are supported in this version and they are mutually exclusive + DWORD AuthScheme, // must be one of the supported Auth Schemes returned from WinHttpQueryAuthSchemes() + WCHAR * pwszUserName, // 1) NULL if default creds is to be used, in which case pszPassword will be ignored + WCHAR * pwszPassword, // 1) "" == Blank Password; 2)Parameter ignored if pszUserName is NULL; 3) Invalid to pass in NULL if pszUserName is not NULL + VOID * pAuthParams); + __declspec(dllimport) BOOL __stdcall WinHttpQueryHeaders(HINTERNET hRequest, DWORD dwInfoLevel, WCHAR const *pwszName, VOID *lpBuffer, DWORD *lpdwBufferLength, DWORD *lpdwIndex); + __declspec(dllimport) BOOL __stdcall WinHttpReceiveResponse(HINTERNET hRequest, VOID *lpReserved); + __declspec(dllimport) WINHTTP_STATUS_CALLBACK __stdcall WinHttpSetStatusCallback(HINTERNET hInternet, WINHTTP_STATUS_CALLBACK lpfnInternetCallback, DWORD dwNotificationFlags, DWORD_PTR dwReserved); + } + + // NOTE: um/DbgHelp.h ////////////////////////////////////////////////////////////////////////// + #define SYMOPT_CASE_INSENSITIVE 0x00000001 + #define SYMOPT_UNDNAME 0x00000002 + #define SYMOPT_DEFERRED_LOADS 0x00000004 + #define SYMOPT_NO_CPP 0x00000008 + #define SYMOPT_LOAD_LINES 0x00000010 + #define SYMOPT_OMAP_FIND_NEAREST 0x00000020 + #define SYMOPT_LOAD_ANYTHING 0x00000040 + #define SYMOPT_IGNORE_CVREC 0x00000080 + #define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 + #define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 + #define SYMOPT_EXACT_SYMBOLS 0x00000400 + #define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 + #define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 + #define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 + #define SYMOPT_PUBLICS_ONLY 0x00004000 + #define SYMOPT_NO_PUBLICS 0x00008000 + #define SYMOPT_AUTO_PUBLICS 0x00010000 + #define SYMOPT_NO_IMAGE_SEARCH 0x00020000 + #define SYMOPT_SECURE 0x00040000 + #define SYMOPT_NO_PROMPTS 0x00080000 + #define SYMOPT_OVERWRITE 0x00100000 + #define SYMOPT_IGNORE_IMAGEDIR 0x00200000 + #define SYMOPT_FLAT_DIRECTORY 0x00400000 + #define SYMOPT_FAVOR_COMPRESSED 0x00800000 + #define SYMOPT_ALLOW_ZERO_ADDRESS 0x01000000 + #define SYMOPT_DISABLE_SYMSRV_AUTODETECT 0x02000000 + #define SYMOPT_READONLY_CACHE 0x04000000 + #define SYMOPT_SYMPATH_LAST 0x08000000 + #define SYMOPT_DISABLE_FAST_SYMBOLS 0x10000000 + #define SYMOPT_DISABLE_SYMSRV_TIMEOUT 0x20000000 + #define SYMOPT_DISABLE_SRVSTAR_ON_STARTUP 0x40000000 + #define SYMOPT_DEBUG 0x80000000 + + #define MAX_SYM_NAME 2000 + + typedef enum { + AddrMode1616, + AddrMode1632, + AddrModeReal, + AddrModeFlat + } ADDRESS_MODE; + + typedef struct _tagADDRESS64 { + DWORD64 Offset; + WORD Segment; + ADDRESS_MODE Mode; + } ADDRESS64, *LPADDRESS64; + + + typedef struct _KDHELP64 { + DWORD64 Thread; + DWORD ThCallbackStack; + DWORD ThCallbackBStore; + DWORD NextCallback; + DWORD FramePointer; + DWORD64 KiCallUserMode; + DWORD64 KeUserCallbackDispatcher; + DWORD64 SystemRangeStart; + DWORD64 KiUserExceptionDispatcher; + DWORD64 StackBase; + DWORD64 StackLimit; + DWORD BuildVersion; + DWORD RetpolineStubFunctionTableSize; + DWORD64 RetpolineStubFunctionTable; + DWORD RetpolineStubOffset; + DWORD RetpolineStubSize; + DWORD64 Reserved0[2]; + } KDHELP64, *PKDHELP64; + + typedef struct _tagSTACKFRAME64 { + ADDRESS64 AddrPC; // program counter + ADDRESS64 AddrReturn; // return address + ADDRESS64 AddrFrame; // frame pointer + ADDRESS64 AddrStack; // stack pointer + ADDRESS64 AddrBStore; // backing store pointer + VOID *FuncTableEntry; // pointer to pdata/fpo or NULL + DWORD64 Params[4]; // possible arguments to the function + BOOL Far; // WOW far call + BOOL Virtual; // is this a virtual frame? + DWORD64 Reserved[3]; + KDHELP64 KdHelp; + } STACKFRAME64; + + typedef struct _IMAGEHLP_LINEW64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) + VOID *Key; // internal + DWORD LineNumber; // line number in file + WCHAR *FileName; // full filename + DWORD64 Address; // first instruction of line + } IMAGEHLP_LINEW64; + + typedef struct _SYMBOL_INFOW { + ULONG SizeOfStruct; + ULONG TypeIndex; // Type Index of symbol + ULONG64 Reserved[2]; + ULONG Index; + ULONG Size; + ULONG64 ModBase; // Base Address of module comtaining this symbol + ULONG Flags; + ULONG64 Value; // Value of symbol, ValuePresent should be 1 + ULONG64 Address; // Address of symbol including base address of module + ULONG Register; // register holding value or pointer to value + ULONG Scope; // scope of the symbol + ULONG Tag; // pdb classification + ULONG NameLen; // Actual length of name + ULONG MaxNameLen; + WCHAR Name[1]; // Name of symbol + } SYMBOL_INFOW; + + typedef BOOL (__stdcall READ_PROCESS_MEMORY_ROUTINE64)(HANDLE hProcess, DWORD64 qwBaseAddress, VOID *lpBuffer, DWORD nSize, DWORD *lpNumberOfBytesRead); + typedef VOID * (__stdcall FUNCTION_TABLE_ACCESS_ROUTINE64)(HANDLE ahProcess, DWORD64 AddrBase); + typedef DWORD64(__stdcall GET_MODULE_BASE_ROUTINE64)(HANDLE hProcess, DWORD64 Address); + typedef DWORD64(__stdcall TRANSLATE_ADDRESS_ROUTINE64)(HANDLE hProcess, HANDLE hThread, ADDRESS64 *lpaddr); + + extern "C" + { + __declspec(dllimport) BOOL __stdcall StackWalk64 (DWORD MachineType, HANDLE hProcess, HANDLE hThread, STACKFRAME64 *StackFrame, VOID *ContextRecord, READ_PROCESS_MEMORY_ROUTINE64 *ReadMemoryRoutine, FUNCTION_TABLE_ACCESS_ROUTINE64 *FunctionTableAccessRoutine, GET_MODULE_BASE_ROUTINE64 *GetModuleBaseRoutine, TRANSLATE_ADDRESS_ROUTINE64 *TranslateAddress); + __declspec(dllimport) BOOL __stdcall SymFromAddrW (HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, SYMBOL_INFOW *Symbol); + __declspec(dllimport) VOID * __stdcall SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase); + __declspec(dllimport) BOOL __stdcall SymGetLineFromAddrW64 (HANDLE hProcess, DWORD64 dwAddr, DWORD *pdwDisplacement, IMAGEHLP_LINEW64 *Line); + __declspec(dllimport) DWORD64 __stdcall SymGetModuleBase64 (HANDLE hProcess, DWORD64 qwAddr); + __declspec(dllimport) BOOL __stdcall SymRefreshModuleList (HANDLE hProcess); + }; + + // NOTE: um/errhandlingapi.h /////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) DWORD __stdcall GetLastError(VOID); + } + + // NOTE: um/libloaderapi.h ///////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) HMODULE __stdcall LoadLibraryA (const CHAR *lpLibFileName); + __declspec(dllimport) BOOL __stdcall FreeLibrary (HMODULE hLibModule); + __declspec(dllimport) void * __stdcall GetProcAddress (HMODULE hModule, const CHAR *lpProcName); + __declspec(dllimport) HMODULE __stdcall GetModuleHandleA (const CHAR *lpModuleName); + __declspec(dllimport) DWORD __stdcall GetModuleFileNameW(HMODULE hModule, WCHAR *lpFilename, DWORD nSize); + } + + // NOTE: um/synchapi.h ///////////////////////////////////////////////////////////////////////// + typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE; + + extern "C" + { + __declspec(dllimport) VOID __stdcall InitializeConditionVariable (CONDITION_VARIABLE *ConditionVariable); + __declspec(dllimport) VOID __stdcall WakeConditionVariable (CONDITION_VARIABLE *ConditionVariable); + __declspec(dllimport) VOID __stdcall WakeAllConditionVariable (CONDITION_VARIABLE *ConditionVariable); + __declspec(dllimport) BOOL __stdcall SleepConditionVariableCS (CONDITION_VARIABLE *ConditionVariable, CRITICAL_SECTION *CriticalSection, DWORD dwMilliseconds); + + __declspec(dllimport) VOID __stdcall InitializeCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) VOID __stdcall EnterCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) VOID __stdcall LeaveCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) BOOL __stdcall InitializeCriticalSectionAndSpinCount(CRITICAL_SECTION *lpCriticalSection, DWORD dwSpinCount); + __declspec(dllimport) BOOL __stdcall InitializeCriticalSectionEx (CRITICAL_SECTION *lpCriticalSection, DWORD dwSpinCount, DWORD Flags); + __declspec(dllimport) DWORD __stdcall SetCriticalSectionSpinCount (CRITICAL_SECTION *lpCriticalSection, DWORD dwSpinCount); + __declspec(dllimport) BOOL __stdcall TryEnterCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) VOID __stdcall DeleteCriticalSection (CRITICAL_SECTION *lpCriticalSection); + + __declspec(dllimport) DWORD __stdcall WaitForSingleObject (HANDLE hHandle, DWORD dwMilliseconds); + __declspec(dllimport) BOOL __stdcall ReleaseSemaphore (HANDLE hSemaphore, LONG lReleaseCount, LONG *lpPreviousCount); + __declspec(dllimport) VOID __stdcall Sleep (DWORD dwMilliseconds); + } + + // NOTE: um/profileapi.h /////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall QueryPerformanceCounter (LARGE_INTEGER* lpPerformanceCount); + __declspec(dllimport) BOOL __stdcall QueryPerformanceFrequency(LARGE_INTEGER* lpFrequency); + } + + // NOTE: um/processthreadsapi.h //////////////////////////////////////////////////////////////// + typedef struct _PROCESS_INFORMATION { + HANDLE hProcess; + HANDLE hThread; + DWORD dwProcessId; + DWORD dwThreadId; + } PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION; + + typedef struct _STARTUPINFOW { + DWORD cb; + WCHAR *lpReserved; + WCHAR *lpDesktop; + WCHAR *lpTitle; + DWORD dwX; + DWORD dwY; + DWORD dwXSize; + DWORD dwYSize; + DWORD dwXCountChars; + DWORD dwYCountChars; + DWORD dwFillAttribute; + DWORD dwFlags; + WORD wShowWindow; + WORD cbReserved2; + BYTE *lpReserved2; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; + } STARTUPINFOW, *LPSTARTUPINFOW; + + typedef DWORD (__stdcall *PTHREAD_START_ROUTINE)( + VOID *lpThreadParameter + ); + typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall CreateProcessW (WCHAR const *lpApplicationName, WCHAR *lpCommandLine, SECURITY_ATTRIBUTES *lpProcessAttributes, SECURITY_ATTRIBUTES *lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, VOID *lpEnvironment, WCHAR const *lpCurrentDirectory, STARTUPINFOW *lpStartupInfo, PROCESS_INFORMATION *lpProcessInformation); + __declspec(dllimport) HANDLE __stdcall CreateThread (SECURITY_ATTRIBUTES *lpThreadAttributes, SIZE_T dwStackSize, PTHREAD_START_ROUTINE lpStartAddress, VOID *lpParameter, DWORD dwCreationFlags, DWORD *lpThreadId); + __declspec(dllimport) DWORD __stdcall GetCurrentThreadId(VOID); + __declspec(dllimport) BOOL __stdcall GetExitCodeProcess(HANDLE hProcess, DWORD *lpExitCode); + __declspec(dllimport) void __stdcall ExitProcess (UINT uExitCode); + } + + // NOTE: um/memoryapi.h //////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) VOID * __stdcall VirtualAlloc (VOID *lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect); + __declspec(dllimport) BOOL __stdcall VirtualProtect(VOID *lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD *lpflOldProtect); + __declspec(dllimport) BOOL __stdcall VirtualFree (VOID *lpAddress, SIZE_T dwSize, DWORD dwFreeType); + } + + // NOTE: shared/bcrypt.h /////////////////////////////////////////////////////////////////////// + typedef VOID *BCRYPT_ALG_HANDLE; + typedef LONG NTSTATUS; + + extern "C" + { + __declspec(dllimport) NTSTATUS __stdcall BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *phAlgorithm, const WCHAR *pszAlgId, const WCHAR *pszImplementation, ULONG dwFlags); + __declspec(dllimport) NTSTATUS __stdcall BCryptGenRandom (BCRYPT_ALG_HANDLE hAlgorithm, UCHAR *pbBuffer, ULONG cbBuffer, ULONG dwFlags); + } + + // NOTE: um/shellapi.h ///////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) HINSTANCE __stdcall ShellExecuteA(HWND hwnd, CHAR const *lpOperation, CHAR const *lpFile, CHAR const *lpParameters, CHAR const *lpDirectory, INT nShowCmd); + __declspec(dllimport) HINSTANCE __stdcall ShellExecuteW(HWND hwnd, WCHAR const *lpOperation, WCHAR const *lpFile, WCHAR const *lpParameters, WCHAR const *lpDirectory, INT nShowCmd); + } + + // NOTE: um/debugapi.h ///////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall IsDebuggerPresent(); + } + + // NOTE: um/namedpipeapi.h ///////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall CreatePipe (HANDLE *hReadPipe, HANDLE *hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize); + __declspec(dllimport) BOOL __stdcall PeekNamedPipe(HANDLE hNamedPipe, VOID *lpBuffer, DWORD nBufferSize, DWORD *lpBytesRead, DWORD *lpTotalBytesAvail, DWORD *lpBytesLeftThisMessage); + } + + // NOTE: um/handleapi.h //////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall SetHandleInformation(HANDLE hObject, DWORD dwMask, DWORD dwFlags); + } + + // NOTE: um/commdlg.h ////////////////////////////////////////////////////////////////////////// + typedef UINT_PTR (__stdcall *LPOFNHOOKPROC)(HWND, UINT, WPARAM, LPARAM); + typedef struct tagOFNW { + DWORD lStructSize; + HWND hwndOwner; + HINSTANCE hInstance; + WCHAR const * lpstrFilter; + LPWSTR lpstrCustomFilter; + DWORD nMaxCustFilter; + DWORD nFilterIndex; + LPWSTR lpstrFile; + DWORD nMaxFile; + LPWSTR lpstrFileTitle; + DWORD nMaxFileTitle; + WCHAR const * lpstrInitialDir; + WCHAR const * lpstrTitle; + DWORD Flags; + WORD nFileOffset; + WORD nFileExtension; + WCHAR const * lpstrDefExt; + LPARAM lCustData; + LPOFNHOOKPROC lpfnHook; + WCHAR const * lpTemplateName; + #ifdef _MAC + LPEDITMENU lpEditInfo; + LPCSTR lpstrPrompt; + #endif + #if (_WIN32_WINNT >= 0x0500) + void * pvReserved; + DWORD dwReserved; + DWORD FlagsEx; + #endif // (_WIN32_WINNT >= 0x0500) + } OPENFILENAMEW, *LPOPENFILENAMEW; + + + #define OFN_READONLY 0x00000001 + #define OFN_OVERWRITEPROMPT 0x00000002 + #define OFN_HIDEREADONLY 0x00000004 + #define OFN_NOCHANGEDIR 0x00000008 + #define OFN_SHOWHELP 0x00000010 + #define OFN_ENABLEHOOK 0x00000020 + #define OFN_ENABLETEMPLATE 0x00000040 + #define OFN_ENABLETEMPLATEHANDLE 0x00000080 + #define OFN_NOVALIDATE 0x00000100 + #define OFN_ALLOWMULTISELECT 0x00000200 + #define OFN_EXTENSIONDIFFERENT 0x00000400 + #define OFN_PATHMUSTEXIST 0x00000800 + #define OFN_FILEMUSTEXIST 0x00001000 + #define OFN_CREATEPROMPT 0x00002000 + #define OFN_SHAREAWARE 0x00004000 + #define OFN_NOREADONLYRETURN 0x00008000 + #define OFN_NOTESTFILECREATE 0x00010000 + #define OFN_NONETWORKBUTTON 0x00020000 + #define OFN_NOLONGNAMES 0x00040000 // force no long names for 4.x modules + #if(WINVER >= 0x0400) + #define OFN_EXPLORER 0x00080000 // new look commdlg + #define OFN_NODEREFERENCELINKS 0x00100000 + #define OFN_LONGNAMES 0x00200000 // force long names for 3.x modules + // OFN_ENABLEINCLUDENOTIFY and OFN_ENABLESIZING require + // Windows 2000 or higher to have any effect. + #define OFN_ENABLEINCLUDENOTIFY 0x00400000 // send include message to callback + #define OFN_ENABLESIZING 0x00800000 + #endif /* WINVER >= 0x0400 */ + #if (_WIN32_WINNT >= 0x0500) + #define OFN_DONTADDTORECENT 0x02000000 + #define OFN_FORCESHOWHIDDEN 0x10000000 // Show All files including System and hidden files + #endif // (_WIN32_WINNT >= 0x0500) + + //FlagsEx Values + #if (_WIN32_WINNT >= 0x0500) + #define OFN_EX_NOPLACESBAR 0x00000001 + #endif // (_WIN32_WINNT >= 0x0500) + + extern "C" + { + __declspec(dllimport) BOOL __stdcall GetSaveFileNameW(LPOPENFILENAMEW); + __declspec(dllimport) BOOL __stdcall GetOpenFileNameW(LPOPENFILENAMEW); + } + + // NOTE: um/shlwapi.h ////////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall PathRelativePathToW(WCHAR *pszPath, WCHAR const *pszFrom, DWORD dwAttrFrom, WCHAR const *pszTo, DWORD dwAttrTo); + __declspec(dllimport) BOOL __stdcall PathIsRelativeW(WCHAR *pszPath); + } + + // NOTE: um/pathcch.h ////////////////////////////////////////////////////////////////////////// + typedef enum PATHCCH_OPTIONS + { + PATHCCH_NONE = 0x0, + + // This option allows applications to gain access to long paths. It has two + // different behaviors. For process configured to enable long paths it will allow + // the returned path to be longer than the max path limit that is normally imposed. + // For process that are not this option will convert long paths into the extended + // length DOS device form (with \\?\ prefix) when the path is longer than the limit. + // This form is not length limited by the Win32 file system API on all versions of Windows. + // This second behavior is the same behavior for OSes that don't have the long path feature. + // This can not be specified with PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH. + PATHCCH_ALLOW_LONG_PATHS = 0x01, + + // Can only be used when PATHCCH_ALLOW_LONG_PATHS is specified. This + // Forces the API to treat the caller as long path enabled, independent of the + // process's long name enabled state. Cannot be used with PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS. + PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS = 0x02, + + // Can only be used when PATHCCH_ALLOW_LONG_PATHS is specified. This + // Forces the API to treat the caller as long path disabled, independent of the + // process's long name enabled state. Cannot be used with PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS. + PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS = 0x04, + + // Disable the normalization of path segments that includes removing trailing dots and spaces. + // This enables access to paths that win32 path normalization will block. + PATHCCH_DO_NOT_NORMALIZE_SEGMENTS = 0x08, + + // Convert the input path into the extended length DOS device path form (with the \\?\ prefix) + // if not already in that form. This enables access to paths that are otherwise not addressable + // due to Win32 normalization rules (that can strip trailing dots and spaces) and path + // length limitations. This option implies the same behavior of PATHCCH_DO_NOT_NORMALIZE_SEGMENTS. + // This can not be specified with PATHCCH_ALLOW_LONG_PATHS. + PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH = 0x10, + + // When combining or normalizing a path ensure there is a trailing backslash. + PATHCCH_ENSURE_TRAILING_SLASH = 0x020, + + // Convert forward slashes to back slashes and collapse multiple slashes. + // This is needed to to support sub-path or identity comparisons. + PATHCCH_CANONICALIZE_SLASHES = 0x040, + } PATHCCH_OPTIONS; + + extern "C" + { + __declspec(dllimport) HRESULT __stdcall PathCchCanonicalizeEx(PWSTR pszPathOut, size_t cchPathOut, WCHAR const *pszPathIn, ULONG dwFlags); + }; + + // NOTE: um/errhandlingapi.h /////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) VOID __stdcall RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const ULONG_PTR* lpArguments); + }; + + // NOTE: include/excpt.h /////////////////////////////////////////////////////////////////// + #define EXCEPTION_EXECUTE_HANDLER 1 + #define EXCEPTION_CONTINUE_SEARCH 0 + #define EXCEPTION_CONTINUE_EXECUTION (-1) + + DN_MSVC_WARNING_POP +#endif // !defined(_INC_WINDOWS) +#endif // !defined(DN_OS_WINDOWS_H) +#endif + struct DN_W32Error { unsigned long code; @@ -5440,7 +6806,12 @@ DN_API bool DN_W32_DirWIterate (DN_Str16 path, DN_W32FolderIterato #endif // !defined(DN_OS_WIN32) #elif defined(DN_PLATFORM_POSIX) || defined(DN_PLATFORM_EMSCRIPTEN) // DN: Single header generator inlined this file => #include "OS/dn_os_posix.h" -#pragma once +#if !defined(DN_OS_POSIX_H) +#define DN_OS_POSIX_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif #include #include @@ -5518,6 +6889,7 @@ struct DN_POSIXCore DN_API void DN_Posix_Init(DN_POSIXCore *posix); DN_API void DN_Posix_ThreadSetName(DN_Str8 name); DN_API DN_POSIXProcSelfStatus DN_Posix_ProcSelfStatus(); +#endif // !defined(DN_OS_POSIX_H) #else #error Please define a platform e.g. 'DN_PLATFORM_WIN32' to enable the correct implementation for platform APIs #endif @@ -5526,10 +6898,12 @@ DN_API DN_POSIXProcSelfStatus DN_Posix_ProcSelfStatus(); #if !defined(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" +#if defined(_CLANGD) + // 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" +#endif -// NOTE: DN_OSErrSink ///////////////////////////////////////////////////////////////////////////// +// NOTE: DN_OSErrSink enum DN_OSErrSinkMode { DN_OSErrSinkMode_Nil, // Default behaviour to accumulate errors into the sink @@ -5667,8 +7041,10 @@ DN_API void DN_OS_ErrSinkAppendF_ (DN_OSErrSink *err, #if !defined(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" +#if defined(_CLANGD) + // 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" +#endif #include // operator new @@ -5699,6 +7075,8 @@ DN_API void DN_OS_ErrSinkAppendF_ (DN_OSErrSink *err, #include // emscripten_fetch (for DN_OSHttpResponse) #endif +extern DN_CPUFeatureDecl g_dn_cpu_feature_decl[DN_CPUFeature_Count]; + // NOTE: DN_OSDate ///////////////////////////////////////////////////////////////////////////////// struct DN_OSDateTimeStr8 { @@ -6116,6 +7494,10 @@ DN_API DN_OSHttpResponse DN_OS_HttpRequest (D #if !defined(DN_OS_ALLOCATOR_H) #define DN_OS_ALLOCATOR_H +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + DN_API DN_Arena DN_ArenaFromHeap(DN_U64 size, DN_ArenaFlags flags); DN_API DN_Arena DN_ArenaFromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags); @@ -6124,7 +7506,11 @@ DN_API DN_Arena DN_ArenaFromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags fl #if !defined(DN_OS_CONTAINERS_H) #define DN_OS_CONTAINERS_H -// NOTE: DN_VArray ///////////////////////////////////////////////////////////////////////////////// +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +// NOTE: DN_VArray // TODO(doyle): Add an API for shrinking the array by decomitting pages back to the OS. template struct DN_VArray { @@ -6178,7 +7564,7 @@ enum DN_OSPrintDest DN_OSPrintDest_Err, }; -// NOTE: Print Macros ////////////////////////////////////////////////////////////////////////////// +// NOTE: Print Macros #define DN_OS_PrintOut(string) DN_OS_Print(DN_OSPrintDest_Out, string) #define DN_OS_PrintOutF(fmt, ...) DN_OS_PrintF(DN_OSPrintDest_Out, fmt, ##__VA_ARGS__) #define DN_OS_PrintOutFV(fmt, args) DN_OS_PrintFV(DN_OSPrintDest_Out, fmt, args) @@ -6211,7 +7597,7 @@ enum DN_OSPrintDest #define DN_OS_PrintErrLnFStyle(style, fmt, ...) DN_OS_PrintLnFStyle(DN_OSPrintDest_Err, style, fmt, ##__VA_ARGS__) #define DN_OS_PrintErrLnFVStyle(style, fmt, args) DN_OS_PrintLnFVStyle(DN_OSPrintDest_Err, style, fmt, args); -// NOTE: Print ///////////////////////////////////////////////////////////////////////////////////// +// NOTE: Print DN_API void DN_OS_Print (DN_OSPrintDest dest, DN_Str8 string); DN_API void DN_OS_PrintF (DN_OSPrintDest dest, DN_FMT_ATTRIB char const *fmt, ...); DN_API void DN_OS_PrintFV (DN_OSPrintDest dest, DN_FMT_ATTRIB char const *fmt, va_list args); @@ -6232,10 +7618,12 @@ DN_API void DN_OS_PrintLnFVStyle (DN_OSPrintDest dest, DN_LOGStyle style, #if !defined(DN_OS_STRING_H) #define DN_OS_STRING_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" +#if defined(_CLANGD) + // 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" +#endif -// NOTE: DN_Str8 /////////////////////////////////////////////////////////////////////////////////// +// NOTE: DN_Str8 DN_API DN_Str8 DN_Str8FromFmtVArenaFrame (DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8 DN_Str8FromFmtArenaFrame (DN_FMT_ATTRIB char const *fmt, ...); @@ -6308,15 +7696,7704 @@ DN_API DN_Slice DN_Str8BuilderBuildSliceFromTLS (DN_Str8Bui #if !defined(DN_INC_H) #define DN_INC_H -struct DN_Core +#if defined(_CLANGD) + // DN: Single header generator inlined this file => #include "dn_base_inc.h" +#if !defined(DN_BASE_INC_H) +#define DN_BASE_INC_H + +// NOTE: DN configuration +// All the following configuration options are optional. If omitted, DN has default behaviours to +// handle the various options. +// +// Platform Target +// Define one of the following directives to configure this library to compile for that platform. +// By default, the library will auto-detect the current host platform and select that as the +// target platform. +// +// DN_PLATFORM_EMSCRIPTEN +// DN_PLATFORM_POSIX +// DN_PLATFORM_WIN32 +// +// For example +// +// #define DN_PLATFORM_WIN32 +// +// Will ensure that is included and the OS layer is implemented using Win32 +// primitives. +// +// Static functions +// All public functions in the DN library are prefixed with the macro '#define DN_API'. By +// default 'DN_API' is not defined to anything. Define +// +// DN_STATIC_API +// +// To replace all the prefixed with 'static' ensuring that the functions in the library do not +// export an entry into the linking table and thereby optimise compilation times as the linker +// will not try to resolve symbols from other translation units from the the unit including the +// DN library. +// +// Using the in-built replacement header for (requires dn_os_inc.h) +// If you are building DN for the Windows platform, is a large legacy header that +// applications have to link to use Windows syscalls. By default DN library uses a replacement +// header for all the Windows functions that it uses in the OS layer removing the need to include +// to improve compilation times. This can be disabled by defining: +// +// DN_NO_WINDOWS_H_REPLACEMENT_HEADER +// +// To instead use . DN automatically detects if is included in an earlier +// translation unit and will automatically disable the in-built replacement header in which case +// this does not need to be defined. +// +// Freestanding +// The base layer can be used without an OS implementation by defining DN_FREESTANDING like: +// +// #define DN_FREESTANDING +// +// This means functionality that relies on the OS like printing, memory allocation, stack traces +// and so forth are disabled. + +// DN: Single header generator commented out this header => #include "Base/dn_base_compiler.h" +#if !defined(DN_BASE_COMPILER_H) +#define DN_BASE_COMPILER_H + +// NOTE: Compiler identification +// Warning! Order is important here, clang-cl on Windows defines _MSC_VER +#if defined(_MSC_VER) + #if defined(__clang__) + #define DN_COMPILER_CLANG_CL + #define DN_COMPILER_CLANG + #else + #define DN_COMPILER_MSVC + #endif +#elif defined(__clang__) + #define DN_COMPILER_CLANG +#elif defined(__GNUC__) + #define DN_COMPILER_GCC +#endif + +// NOTE: __has_feature +// MSVC for example does not support the feature detection macro for instance so we compile it out +#if defined(__has_feature) + #define DN_HAS_FEATURE(expr) __has_feature(expr) +#else + #define DN_HAS_FEATURE(expr) 0 +#endif + +// NOTE: __has_builtin +// MSVC for example does not support the feature detection macro for instance so we compile it out +#if defined(__has_builtin) + #define DN_HAS_BUILTIN(expr) __has_builtin(expr) +#else + #define DN_HAS_BUILTIN(expr) 0 +#endif + +// NOTE: Warning suppression macros +#if defined(DN_COMPILER_MSVC) + #define DN_MSVC_WARNING_PUSH __pragma(warning(push)) + #define DN_MSVC_WARNING_DISABLE(...) __pragma(warning(disable :##__VA_ARGS__)) + #define DN_MSVC_WARNING_POP __pragma(warning(pop)) +#else + #define DN_MSVC_WARNING_PUSH + #define DN_MSVC_WARNING_DISABLE(...) + #define DN_MSVC_WARNING_POP +#endif + +#if defined(DN_COMPILER_CLANG) || defined(DN_COMPILER_GCC) || defined(DN_COMPILER_CLANG_CL) + #define DN_GCC_WARNING_PUSH _Pragma("GCC diagnostic push") + #define DN_GCC_WARNING_DISABLE_HELPER_0(x) #x + #define DN_GCC_WARNING_DISABLE_HELPER_1(y) DN_GCC_WARNING_DISABLE_HELPER_0(GCC diagnostic ignored #y) + #define DN_GCC_WARNING_DISABLE(warning) _Pragma(DN_GCC_WARNING_DISABLE_HELPER_1(warning)) + #define DN_GCC_WARNING_POP _Pragma("GCC diagnostic pop") +#else + #define DN_GCC_WARNING_PUSH + #define DN_GCC_WARNING_DISABLE(...) + #define DN_GCC_WARNING_POP +#endif + +// NOTE: Host OS identification +#if defined(_WIN32) + #define DN_OS_WIN32 +#elif defined(__gnu_linux__) || defined(__linux__) + #define DN_OS_UNIX +#endif + +// NOTE: Platform identification +#if !defined(DN_PLATFORM_EMSCRIPTEN) && \ + !defined(DN_PLATFORM_POSIX) && \ + !defined(DN_PLATFORM_WIN32) + #if defined(__aarch64__) || defined(_M_ARM64) + #define DN_PLATFORM_ARM64 + #elif defined(__EMSCRIPTEN__) + #define DN_PLATFORM_EMSCRIPTEN + #elif defined(DN_OS_WIN32) + #define DN_PLATFORM_WIN32 + #else + #define DN_PLATFORM_POSIX + #endif +#endif + +// NOTE: Windows crap +#if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) + #if defined(_CRT_SECURE_NO_WARNINGS) + #define DN_CRT_SECURE_NO_WARNINGS_PREVIOUSLY_DEFINED + #else + #define _CRT_SECURE_NO_WARNINGS + #endif +#endif + +// NOTE: Force Inline +#if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) + #define DN_FORCE_INLINE __forceinline +#else + #define DN_FORCE_INLINE inline __attribute__((always_inline)) +#endif + +// NOTE: Function/Variable Annotations +#if defined(DN_STATIC_API) + #define DN_API static +#else + #define DN_API +#endif + +// NOTE: C/CPP Literals +// Declare struct literals that work in both C and C++ because the syntax is different between +// languages. +#if 0 + struct Foo { int a; } + struct Foo foo = DN_LITERAL(Foo){32}; // Works on both C and C++ +#endif + +#if defined(__cplusplus) + #define DN_Literal(T) T +#else + #define DN_Literal(T) (T) +#endif + +// NOTE: Thread Locals +#if defined(__cplusplus) + #define DN_THREAD_LOCAL thread_local +#else + #define DN_THREAD_LOCAL _Thread_local +#endif + +// NOTE: C variadic argument annotations +// TODO: Other compilers +#if defined(DN_COMPILER_MSVC) + #define DN_FMT_ATTRIB _Printf_format_string_ +#else + #define DN_FMT_ATTRIB +#endif + +// NOTE: Type Cast +#define DN_Cast(val) (val) + +// NOTE: Zero initialisation macro +#if defined(__cplusplus) + #define DN_ZeroInit {} +#else + #define DN_ZeroInit {0} +#endif + +// NOTE: Address sanitizer +#if !defined(DN_ASAN_POISON) + #define DN_ASAN_POISON 0 +#endif + +#if !defined(DN_ASAN_VET_POISON) + #define DN_ASAN_VET_POISON 0 +#endif + +#define DN_ASAN_POISON_ALIGNMENT 8 + +#if !defined(DN_ASAN_POISON_GUARD_SIZE) + #define DN_ASAN_POISON_GUARD_SIZE 128 +#endif + +#if DN_HAS_FEATURE(address_sanitizer) || defined(__SANITIZE_ADDRESS__) + #include +#endif +#endif // !defined(DN_BASE_COMPILER_H) +// DN: Single header generator commented out this header => #include "Base/dn_base.h" +#if !defined(DN_BASE_H) +#define DN_BASE_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +// NOTE: Macros +#define DN_Stringify(x) #x +#define DN_TokenCombine2(x, y) x ## y +#define DN_TokenCombine(x, y) DN_TokenCombine2(x, y) + +#include // va_list +#include +#include +#include +#include // PRIu64... + +#if !defined(DN_OS_WIN32) +#include // exit() +#endif + +#define DN_ForIndexU(index, size) DN_USize index = 0; index < size; index++ +#define DN_ForIndexI(index, size) DN_ISize index = 0; index < size; index++ +#define DN_ForItSize(it, T, array, size) struct { DN_USize index; T *data; } it = {0, &(array)[0]}; it.index < (size); it.index++, it.data = (array) + it.index +#define DN_ForItSizeReverse(it, T, array, size) struct { DN_USize index; T *data; } it = {(size) - 1, &(array)[size - 1]}; it.index < (size); it.index--, it.data = (array) + it.index +#define DN_ForIt(it, T, array) struct { DN_USize index; T *data; } it = {0, &(array)->data[0]}; it.index < (array)->size; it.index++, it.data = ((array)->data) + it.index +#define DN_ForLinkedListIt(it, T, list) struct { DN_USize index; T *data; } it = {0, list}; it.data; it.index++, it.data = ((it).data->next) +#define DN_ForItCArray(it, T, array) struct { DN_USize index; T *data; } it = {0, &(array)[0]}; it.index < DN_ArrayCountU(array); it.index++, it.data = (array) + it.index + +#define DN_AlignUpPowerOfTwo(value, pot) (((uintptr_t)(value) + ((uintptr_t)(pot) - 1)) & ~((uintptr_t)(pot) - 1)) +#define DN_AlignDownPowerOfTwo(value, pot) ((uintptr_t)(value) & ~((uintptr_t)(pot) - 1)) +#define DN_IsPowerOfTwo(value) ((((uintptr_t)(value)) & (((uintptr_t)(value)) - 1)) == 0) +#define DN_IsPowerOfTwoAligned(value, pot) ((((uintptr_t)value) & (((uintptr_t)pot) - 1)) == 0) + +// NOTE: String.h Dependencies +#if !defined(DN_Memcpy) || !defined(DN_Memset) || !defined(DN_Memcmp) || !defined(DN_Memmove) + #include + #if !defined(DN_Memcpy) + #define DN_Memcpy(dest, src, count) memcpy((dest), (src), (count)) + #endif + #if !defined(DN_Memset) + #define DN_Memset(dest, value, count) memset((dest), (value), (count)) + #endif + #if !defined(DN_Memcmp) + #define DN_Memcmp(lhs, rhs, count) memcmp((lhs), (rhs), (count)) + #endif + #if !defined(DN_Memmove) + #define DN_Memmove(dest, src, count) memmove((dest), (src), (count)) + #endif +#endif + +// NOTE: Math.h Dependencies +#if !defined(DN_SqrtF32) || !defined(DN_SinF32) || !defined(DN_CosF32) || !defined(DN_TanF32) + #include + #if !defined(DN_SqrtF32) + #define DN_SqrtF32(val) sqrtf(val) + #endif + #if !defined(DN_SinF32) + #define DN_SinF32(val) sinf(val) + #endif + #if !defined(DN_CosF32) + #define DN_CosF32(val) cosf(val) + #endif + #if !defined(DN_TanF32) + #define DN_TanF32(val) tanf(val) + #endif +#endif + +// NOTE: Math +#define DN_PiF32 3.14159265359f + +#define DN_DegreesToRadians(degrees) ((degrees) * (DN_PI / 180.0f)) +#define DN_RadiansToDegrees(radians) ((radians) * (180.f * DN_PI)) + +#define DN_Abs(val) (((val) < 0) ? (-(val)) : (val)) +#define DN_Max(a, b) (((a) > (b)) ? (a) : (b)) +#define DN_Min(a, b) (((a) < (b)) ? (a) : (b)) +#define DN_Clamp(val, lo, hi) DN_Max(DN_Min(val, hi), lo) +#define DN_Squared(val) ((val) * (val)) + +#define DN_Swap(a, b) \ + do { \ + auto temp = a; \ + a = b; \ + b = temp; \ + } while (0) + +// NOTE: Size +#define DN_SizeOfI(val) DN_Cast(ptrdiff_t)sizeof(val) +#define DN_ArrayCountU(array) (sizeof(array)/(sizeof((array)[0]))) +#define DN_ArrayCountI(array) (DN_ISize)DN_ArrayCountU(array) +#define DN_CharCountU(string) (sizeof(string) - 1) + +// NOTE: SI Byte +#define DN_Bytes(val) ((DN_U64)val) +#define DN_Kilobytes(val) ((DN_U64)1024 * DN_Bytes(val)) +#define DN_Megabytes(val) ((DN_U64)1024 * DN_Kilobytes(val)) +#define DN_Gigabytes(val) ((DN_U64)1024 * DN_Megabytes(val)) + +// NOTE: Time +#define DN_MsFromSec(val) ((val) * 1000ULL) +#define DN_SecFromMins(val) ((val) * 60ULL) +#define DN_SecFromHours(val) (DN_SecFromMins(val) * 60ULL) +#define DN_SecFromDays(val) (DN_SecFromHours(val) * 24ULL) +#define DN_SecFromWeeks(val) (DN_SecFromDays(val) * 7ULL) +#define DN_SecFromYears(val) (DN_SecFromWeeks(val) * 52ULL) + +// NOTE: Debug Break +#if !defined(DN_DebugBreak) + #if defined(NDEBUG) + #define DN_DebugBreak + #else + #if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) + #define DN_DebugBreak __debugbreak() + #elif DN_HAS_BUILTIN(__builtin_debugtrap) + #define DN_DebugBreak __builtin_debugtrap() + #elif DN_HAS_BUILTIN(__builtin_trap) || defined(DN_COMPILER_GCC) + #define DN_DebugBreak __builtin_trap() + #else + #include + #if defined(SIGTRAP) + #define DN_DebugBreak raise(SIGTRAP) + #else + #define DN_DebugBreak raise(SIGABRT) + #endif + #endif + #endif +#endif + +// NOTE: Byte swaps +#define DN_ByteSwap64(u64) (((((u64) >> 56) & 0xFF) << 0) | \ + ((((u64) >> 48) & 0xFF) << 8) | \ + ((((u64) >> 40) & 0xFF) << 16) | \ + ((((u64) >> 32) & 0xFF) << 24) | \ + ((((u64) >> 24) & 0xFF) << 32) | \ + ((((u64) >> 16) & 0xFF) << 40) | \ + ((((u64) >> 8) & 0xFF) << 48) | \ + ((((u64) >> 0) & 0xFF) << 56)) + +// NOTE: Types +typedef intptr_t DN_ISize; +typedef uintptr_t DN_USize; + +typedef int8_t DN_I8; +typedef int16_t DN_I16; +typedef int32_t DN_I32; +typedef int64_t DN_I64; + +typedef uint8_t DN_U8; +typedef uint16_t DN_U16; +typedef uint32_t DN_U32; +typedef uint64_t DN_U64; + +typedef uintptr_t DN_UPtr; +typedef float DN_F32; +typedef double DN_F64; +typedef unsigned int DN_UInt; +typedef DN_I32 DN_B32; + +#define DN_F32_MAX 3.402823466e+38F +#define DN_F32_MIN 1.175494351e-38F +#define DN_F64_MAX 1.7976931348623158e+308 +#define DN_F64_MIN 2.2250738585072014e-308 +#define DN_USIZE_MAX UINTPTR_MAX +#define DN_ISIZE_MAX INTPTR_MAX +#define DN_ISIZE_MIN INTPTR_MIN + +enum DN_ZMem { - DN_USize mem_allocs_frame; - DN_LeakTracker leak; - #if defined(DN_OS_H) - DN_OSCore os; + DN_ZMem_No, // Memory can be handed out without zero-ing it out + DN_ZMem_Yes, // Memory should be zero-ed out before giving to the callee +}; + +struct DN_Str8 +{ + char *data; // The bytes of the string + DN_USize size; // The number of bytes in the string +}; + +struct DN_Str8x32 { char data[32]; DN_USize size; }; +struct DN_Str8x64 { char data[64]; DN_USize size; }; +struct DN_Str8x128 { char data[128]; DN_USize size; }; +struct DN_Str8x256 { char data[256]; DN_USize size; }; + +struct DN_Hex32 { char data[32]; }; +struct DN_Hex64 { char data[64]; }; +struct DN_Hex128 { char data[128]; }; + +struct DN_HexU64Str8 +{ + char data[(sizeof(DN_U64) * 2) + 1 /*null-terminator*/]; + DN_U8 size; +}; + +enum DN_HexFromU64Type +{ + DN_HexFromU64Type_Nil, + DN_HexFromU64Type_Uppercase, +}; + +struct DN_Str16 // A pointer and length style string that holds slices to UTF16 bytes. +{ + wchar_t *data; // The UTF16 bytes of the string + DN_USize size; // The number of characters in the string +}; + +struct DN_U8x16 { DN_U8 data[16]; }; +struct DN_U8x32 { DN_U8 data[32]; }; +struct DN_U8x64 { DN_U8 data[64]; }; + +template +struct DN_Slice // A pointer and length container of data +{ + T *data; + DN_USize size; + + T *begin() { return data; } + T *end() { return data + size; } + T const *begin() const { return data; } + T const *end() const { return data + size; } +}; + +struct DN_CallSite +{ + DN_Str8 file; + DN_Str8 function; + DN_U32 line; +}; + +#define DN_CALL_SITE DN_CallSite { DN_Str8Lit(__FILE__), DN_Str8Lit(__func__), __LINE__ } + +// NOTE: Defer Macro +#if defined(__cplusplus) +template +struct DN_Defer +{ + Procedure proc; + DN_Defer(Procedure p) : proc(p) {} + ~DN_Defer() { proc(); } +}; + +struct DN_DeferHelper +{ + template + DN_Defer operator+(Lambda lambda) { return DN_Defer(lambda); }; +}; + +#define DN_UniqueName(prefix) DN_TokenCombine(prefix, __LINE__) +#define DN_DEFER const auto DN_UniqueName(defer_lambda_) = DN_DeferHelper() + [&]() +#endif // defined(__cplusplus) + +#define DN_DeferLoop(begin, end) \ + bool DN_UniqueName(once) = (begin, true); \ + DN_UniqueName(once); \ + end, DN_UniqueName(once) = false + + +// NOTE: Intrinsics +// NOTE: DN_AtomicAdd/Exchange return the previous value store in the target +#if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) + #include + #define DN_AtomicCompareExchange64(dest, desired_val, prev_val) _InterlockedCompareExchange64((__int64 volatile *)dest, desired_val, prev_val) + #define DN_AtomicCompareExchange32(dest, desired_val, prev_val) _InterlockedCompareExchange((long volatile *)dest, desired_val, prev_val) + + #define DN_AtomicLoadU64(target) *(target) + #define DN_AtomicLoadU32(target) *(target) + #define DN_AtomicAddU32(target, value) _InterlockedExchangeAdd((long volatile *)target, value) + #define DN_AtomicAddU64(target, value) _InterlockedExchangeAdd64((__int64 volatile *)target, value) + #define DN_AtomicSubU32(target, value) DN_AtomicAddU32(DN_Cast(long volatile *) target, (long)-value) + #define DN_AtomicSubU64(target, value) DN_AtomicAddU64(target, (DN_U64) - value) + + #define DN_CountLeadingZerosU64(value) __lzcnt64(value) + #define DN_CountLeadingZerosU32(value) __lzcnt(value) + #define DN_CPUGetTSC() __rdtsc() + #define DN_CompilerReadBarrierAndCPUReadFence _ReadBarrier(); _mm_lfence() + #define DN_CompilerWriteBarrierAndCPUWriteFence _WriteBarrier(); _mm_sfence() +#elif defined(DN_COMPILER_GCC) || defined(DN_COMPILER_CLANG) + #if defined(__ANDROID__) + #elif defined(DN_PLATFORM_EMSCRIPTEN) + #if !defined(__wasm_simd128__) + #error DN_Base requires -msse2 to be passed to Emscripten + #endif + #include + #else + #include + #endif + + #define DN_AtomicLoadU64(target) __atomic_load_n(x, __ATOMIC_SEQ_CST) + #define DN_AtomicLoadU32(target) __atomic_load_n(x, __ATOMIC_SEQ_CST) + #define DN_AtomicAddU32(target, value) __atomic_fetch_add(target, value, __ATOMIC_ACQ_REL) + #define DN_AtomicAddU64(target, value) __atomic_fetch_add(target, value, __ATOMIC_ACQ_REL) + #define DN_AtomicSubU32(target, value) __atomic_fetch_sub(target, value, __ATOMIC_ACQ_REL) + #define DN_AtomicSubU64(target, value) __atomic_fetch_sub(target, value, __ATOMIC_ACQ_REL) + + #define DN_CountLeadingZerosU64(value) __builtin_clzll(value) + #define DN_CountLeadingZerosU32(value) __builtin_clzl(value) + + #if defined(DN_COMPILER_GCC) + #define DN_CPUGetTSC() __rdtsc() + #else + #define DN_CPUGetTSC() __builtin_readcyclecounter() + #endif + + #if defined(DN_PLATFORM_EMSCRIPTEN) + #define DN_CompilerReadBarrierAndCPUReadFence + #define DN_CompilerWriteBarrierAndCPUWriteFence + #else + #define DN_CompilerReadBarrierAndCPUReadFence asm volatile("lfence" ::: "memory") + #define DN_CompilerWriteBarrierAndCPUWriteFence asm volatile("sfence" ::: "memory") + #endif +#else + #error "Compiler not supported" +#endif + +#if defined(__aarch64__) || defined(_M_X64) || defined(__x86_64__) || defined(__x86_64) + #define DN_CountLeadingZerosUSize(value) DN_CountLeadingZerosU64(value) +#else + #define DN_CountLeadingZerosUSize(value) DN_CountLeadingZerosU32(value) +#endif + +struct DN_CPURegisters +{ + int eax; + int ebx; + int ecx; + int edx; +}; + +union DN_CPUIDResult +{ + DN_CPURegisters reg; + int values[4]; +}; + +struct DN_CPUIDArgs { int eax; int ecx; }; + +#define DN_CPU_FEAT_XMACRO \ + DN_CPU_FEAT_XENTRY(3DNow) \ + DN_CPU_FEAT_XENTRY(3DNowExt) \ + DN_CPU_FEAT_XENTRY(ABM) \ + DN_CPU_FEAT_XENTRY(AES) \ + DN_CPU_FEAT_XENTRY(AVX) \ + DN_CPU_FEAT_XENTRY(AVX2) \ + DN_CPU_FEAT_XENTRY(AVX512F) \ + DN_CPU_FEAT_XENTRY(AVX512DQ) \ + DN_CPU_FEAT_XENTRY(AVX512IFMA) \ + DN_CPU_FEAT_XENTRY(AVX512PF) \ + DN_CPU_FEAT_XENTRY(AVX512ER) \ + DN_CPU_FEAT_XENTRY(AVX512CD) \ + DN_CPU_FEAT_XENTRY(AVX512BW) \ + DN_CPU_FEAT_XENTRY(AVX512VL) \ + DN_CPU_FEAT_XENTRY(AVX512VBMI) \ + DN_CPU_FEAT_XENTRY(AVX512VBMI2) \ + DN_CPU_FEAT_XENTRY(AVX512VNNI) \ + DN_CPU_FEAT_XENTRY(AVX512BITALG) \ + DN_CPU_FEAT_XENTRY(AVX512VPOPCNTDQ) \ + DN_CPU_FEAT_XENTRY(AVX5124VNNIW) \ + DN_CPU_FEAT_XENTRY(AVX5124FMAPS) \ + DN_CPU_FEAT_XENTRY(AVX512VP2INTERSECT) \ + DN_CPU_FEAT_XENTRY(AVX512FP16) \ + DN_CPU_FEAT_XENTRY(CLZERO) \ + DN_CPU_FEAT_XENTRY(CMPXCHG8B) \ + DN_CPU_FEAT_XENTRY(CMPXCHG16B) \ + DN_CPU_FEAT_XENTRY(F16C) \ + DN_CPU_FEAT_XENTRY(FMA) \ + DN_CPU_FEAT_XENTRY(FMA4) \ + DN_CPU_FEAT_XENTRY(FP128) \ + DN_CPU_FEAT_XENTRY(FP256) \ + DN_CPU_FEAT_XENTRY(FPU) \ + DN_CPU_FEAT_XENTRY(MMX) \ + DN_CPU_FEAT_XENTRY(MONITOR) \ + DN_CPU_FEAT_XENTRY(MOVBE) \ + DN_CPU_FEAT_XENTRY(MOVU) \ + DN_CPU_FEAT_XENTRY(MmxExt) \ + DN_CPU_FEAT_XENTRY(PCLMULQDQ) \ + DN_CPU_FEAT_XENTRY(POPCNT) \ + DN_CPU_FEAT_XENTRY(RDRAND) \ + DN_CPU_FEAT_XENTRY(RDSEED) \ + DN_CPU_FEAT_XENTRY(RDTSCP) \ + DN_CPU_FEAT_XENTRY(SHA) \ + DN_CPU_FEAT_XENTRY(SSE) \ + DN_CPU_FEAT_XENTRY(SSE2) \ + DN_CPU_FEAT_XENTRY(SSE3) \ + DN_CPU_FEAT_XENTRY(SSE41) \ + DN_CPU_FEAT_XENTRY(SSE42) \ + DN_CPU_FEAT_XENTRY(SSE4A) \ + DN_CPU_FEAT_XENTRY(SSSE3) \ + DN_CPU_FEAT_XENTRY(TSC) \ + DN_CPU_FEAT_XENTRY(TscInvariant) \ + DN_CPU_FEAT_XENTRY(VAES) \ + DN_CPU_FEAT_XENTRY(VPCMULQDQ) + +enum DN_CPUFeature +{ + #define DN_CPU_FEAT_XENTRY(label) DN_CPUFeature_##label, + DN_CPU_FEAT_XMACRO + #undef DN_CPU_FEAT_XENTRY + DN_CPUFeature_Count, +}; + +struct DN_CPUFeatureDecl +{ + DN_CPUFeature value; + DN_Str8 label; +}; + +struct DN_CPUFeatureQuery +{ + DN_CPUFeature feature; + bool available; +}; + +struct DN_CPUReport +{ + char vendor[4 /*bytes*/ * 3 /*EDX, ECX, EBX*/ + 1 /*null*/]; + char brand[48]; + DN_U64 features[(DN_CPUFeature_Count / (sizeof(DN_U64) * 8)) + 1]; +}; + +struct DN_TicketMutex +{ + unsigned int volatile ticket; // The next ticket to give out to the thread taking the mutex + unsigned int volatile serving; // The ticket ID to block the mutex on until it is returned +}; + +struct DN_U64FromResult +{ + bool success; + DN_U64 value; +}; + +struct DN_I64FromResult +{ + bool success; + DN_I64 value; +}; + +enum DN_MemCommit +{ + DN_MemCommit_No, + DN_MemCommit_Yes, +}; + +typedef DN_U32 DN_MemPage; +enum DN_MemPage_ +{ + // Exception on read/write with a page. This flag overrides the read/write + // access. + DN_MemPage_NoAccess = 1 << 0, + + DN_MemPage_Read = 1 << 1, // Only read permitted on the page. + + // Only write permitted on the page. On Windows this is not supported and + // will be promoted to read+write permissions. + DN_MemPage_Write = 1 << 2, + + DN_MemPage_ReadWrite = DN_MemPage_Read | DN_MemPage_Write, + + // Modifier used in conjunction with previous flags. Raises exception on + // first access to the page, then, the underlying protection flags are + // active. This is supported on Windows, on other OS's using this flag will + // set the OS equivalent of DN_MemPage_NoAccess. + // This flag must only be used in DN_Mem_Protect + DN_MemPage_Guard = 1 << 3, + + // If leak tracing is enabled, this flag will allow the allocation recorded + // from the reserve call to be leaked, e.g. not printed when leaks are + // dumped to the console. + DN_MemPage_AllocRecordLeakPermitted = 1 << 4, + + // If leak tracing is enabled this flag will prevent any allocation record + // from being created in the allocation table at all. If this flag is + // enabled, 'OSMemPage_AllocRecordLeakPermitted' has no effect since the + // record will never be created. + DN_MemPage_NoAllocRecordEntry = 1 << 5, + + // [INTERNAL] Do not use. All flags together do not constitute a correct + // configuration of pages. + DN_MemPage_All = DN_MemPage_NoAccess | + DN_MemPage_ReadWrite | + DN_MemPage_Guard | + DN_MemPage_AllocRecordLeakPermitted | + DN_MemPage_NoAllocRecordEntry, +}; + +#if !defined(DN_ARENA_RESERVE_SIZE) + #define DN_ARENA_RESERVE_SIZE DN_Megabytes(64) +#endif + +#if !defined(DN_ARENA_COMMIT_SIZE) + #define DN_ARENA_COMMIT_SIZE DN_Kilobytes(64) +#endif + +enum DN_Allocator +{ + DN_Allocator_Arena, + DN_Allocator_Pool, +}; + +struct DN_ArenaBlock +{ + DN_ArenaBlock *prev; + DN_U64 used; + DN_U64 commit; + DN_U64 reserve; + DN_U64 reserve_sum; +}; + +typedef DN_U32 DN_ArenaFlags; +enum DN_ArenaFlags_ +{ + DN_ArenaFlags_Nil = 0, + DN_ArenaFlags_NoGrow = 1 << 0, + DN_ArenaFlags_NoPoison = 1 << 1, + DN_ArenaFlags_NoAllocTrack = 1 << 2, + DN_ArenaFlags_AllocCanLeak = 1 << 3, + + // NOTE: Internal flags. Do not use + DN_ArenaFlags_UserBuffer = 1 << 4, + DN_ArenaFlags_MemFuncs = 1 << 5, +}; + +struct DN_ArenaInfo +{ + DN_U64 used; + DN_U64 commit; + DN_U64 reserve; + DN_U64 blocks; +}; + +struct DN_ArenaStats +{ + DN_ArenaInfo info; + DN_ArenaInfo hwm; +}; + +struct DN_ArenaStatsStr8x64 +{ + DN_Str8x64 info; + DN_Str8x64 hwm; +}; + +enum DN_ArenaMemFuncType +{ + DN_ArenaMemFuncType_Nil, + DN_ArenaMemFuncType_Basic, + DN_ArenaMemFuncType_VMem, +}; + +typedef void *(DN_ArenaMemBasicAllocFunc)(DN_USize size); +typedef void (DN_ArenaMemBasicDeallocFunc)(void *ptr); +typedef void *(DN_ArenaMemVMemReserveFunc)(DN_USize size, DN_MemCommit commit, DN_MemPage page_flags); +typedef bool (DN_ArenaMemVMemCommitFunc)(void *ptr, DN_USize size, DN_U32 page_flags); +typedef void (DN_ArenaMemVMemReleaseFunc)(void *ptr, DN_USize size); +struct DN_ArenaMemFuncs +{ + DN_ArenaMemFuncType type; + DN_ArenaMemBasicAllocFunc *basic_alloc; + DN_ArenaMemBasicDeallocFunc *basic_dealloc; + + DN_U32 vmem_page_size; + DN_ArenaMemVMemReserveFunc *vmem_reserve; + DN_ArenaMemVMemCommitFunc *vmem_commit; + DN_ArenaMemVMemReleaseFunc *vmem_release; +}; + +struct DN_Arena +{ + DN_ArenaMemFuncs mem_funcs; + DN_ArenaBlock *curr; + DN_ArenaStats stats; + DN_ArenaFlags flags; + DN_Str8 label; + DN_Arena *prev, *next; +}; + +struct DN_ArenaTempMem +{ + DN_Arena *arena; + DN_U64 used_sum; +}; + +struct DN_ArenaTempMemScope +{ + DN_ArenaTempMemScope(DN_Arena *arena); + ~DN_ArenaTempMemScope(); + DN_ArenaTempMem mem; +}; + +DN_USize const DN_ARENA_HEADER_SIZE = DN_AlignUpPowerOfTwo(sizeof(DN_Arena), 64); + +#if !defined(DN_POOL_DEFAULT_ALIGN) + #define DN_POOL_DEFAULT_ALIGN 16 +#endif + +struct DN_PoolSlot +{ + void *data; + DN_PoolSlot *next; +}; + +enum DN_PoolSlotSize +{ + DN_PoolSlotSize_32B, + DN_PoolSlotSize_64B, + DN_PoolSlotSize_128B, + DN_PoolSlotSize_256B, + DN_PoolSlotSize_512B, + DN_PoolSlotSize_1KiB, + DN_PoolSlotSize_2KiB, + DN_PoolSlotSize_4KiB, + DN_PoolSlotSize_8KiB, + DN_PoolSlotSize_16KiB, + DN_PoolSlotSize_32KiB, + DN_PoolSlotSize_64KiB, + DN_PoolSlotSize_128KiB, + DN_PoolSlotSize_256KiB, + DN_PoolSlotSize_512KiB, + DN_PoolSlotSize_1MiB, + DN_PoolSlotSize_2MiB, + DN_PoolSlotSize_4MiB, + DN_PoolSlotSize_8MiB, + DN_PoolSlotSize_16MiB, + DN_PoolSlotSize_32MiB, + DN_PoolSlotSize_64MiB, + DN_PoolSlotSize_128MiB, + DN_PoolSlotSize_256MiB, + DN_PoolSlotSize_512MiB, + DN_PoolSlotSize_1GiB, + DN_PoolSlotSize_2GiB, + DN_PoolSlotSize_4GiB, + DN_PoolSlotSize_8GiB, + DN_PoolSlotSize_16GiB, + DN_PoolSlotSize_32GiB, + DN_PoolSlotSize_Count, +}; + +struct DN_Pool +{ + DN_Arena *arena; + DN_PoolSlot *slots[DN_PoolSlotSize_Count]; + DN_U8 align; +}; + +struct DN_NibbleFromU8Result +{ + char nibble0; + char nibble1; +}; + +enum DN_Str8EqCase +{ + DN_Str8EqCase_Sensitive, + DN_Str8EqCase_Insensitive, +}; + +enum DN_Str8IsAllType +{ + DN_Str8IsAllType_Digits, + DN_Str8IsAllType_Hex, +}; + +struct DN_Str8BSplitResult +{ + DN_Str8 lhs; + DN_Str8 rhs; +}; + +struct DN_Str8FindResult +{ + bool found; // True if string was found. If false, the subsequent fields below are not set. + DN_USize index; // Index in the buffer where the found string starts + DN_Str8 match; // Matching string in the buffer that was searched + DN_Str8 match_to_end_of_buffer; // Substring containing the found string to the end of the buffer + DN_Str8 after_match_to_end_of_buffer; // Substring starting after the found string to the end of the buffer + DN_Str8 start_to_before_match; // Substring from the start of the buffer up until the found string, not including it +}; + +enum DN_Str8FindFlag +{ + DN_Str8FindFlag_Digit = 1 << 0, // 0-9 + DN_Str8FindFlag_Whitespace = 1 << 1, // '\r', '\t', '\n', ' ' + DN_Str8FindFlag_Alphabet = 1 << 2, // A-Z, a-z + DN_Str8FindFlag_Plus = 1 << 3, // + + DN_Str8FindFlag_Minus = 1 << 4, // - + DN_Str8FindFlag_AlphaNum = DN_Str8FindFlag_Alphabet | DN_Str8FindFlag_Digit, +}; + +enum DN_Str8SplitIncludeEmptyStrings +{ + DN_Str8SplitIncludeEmptyStrings_No, + DN_Str8SplitIncludeEmptyStrings_Yes, +}; + +struct DN_Str8TruncateResult +{ + bool truncated; + DN_Str8 str8; +}; + +struct DN_Str8SplitResult +{ + DN_Str8 *data; + DN_USize count; +}; + +struct DN_Str8Link +{ + DN_Str8 string; // The string + DN_Str8Link *next; // The next string in the linked list + DN_Str8Link *prev; // The prev string in the linked list +}; + +struct DN_Str8Builder +{ + DN_Arena *arena; // Allocator to use to back the string list + DN_Str8Link *head; // First string in the linked list of strings + DN_Str8Link *tail; // Last string in the linked list of strings + DN_USize string_size; // The size in bytes necessary to construct the current string + DN_USize count; // The number of links in the linked list of strings +}; + +enum DN_Str8BuilderAdd +{ + DN_Str8BuilderAdd_Append, + DN_Str8BuilderAdd_Prepend, +}; + +typedef DN_U32 DN_AgeUnit; +enum DN_AgeUnit_ +{ + DN_AgeUnit_Ms = 1 << 0, + DN_AgeUnit_Sec = 1 << 1, + DN_AgeUnit_Min = 1 << 2, + DN_AgeUnit_Hr = 1 << 3, + DN_AgeUnit_Day = 1 << 4, + DN_AgeUnit_Week = 1 << 5, + DN_AgeUnit_Year = 1 << 6, + DN_AgeUnit_FractionalSec = 1 << 7, + DN_AgeUnit_HMS = DN_AgeUnit_Sec | DN_AgeUnit_Min | DN_AgeUnit_Hr, + DN_AgeUnit_All = DN_AgeUnit_Ms | DN_AgeUnit_HMS | DN_AgeUnit_Day | DN_AgeUnit_Week | DN_AgeUnit_Year, +}; + +enum DN_ByteCountType +{ + DN_ByteCountType_B, + DN_ByteCountType_KiB, + DN_ByteCountType_MiB, + DN_ByteCountType_GiB, + DN_ByteCountType_TiB, + DN_ByteCountType_Count, + DN_ByteCountType_Auto, +}; + +struct DN_ByteCountResult +{ + DN_ByteCountType type; + DN_Str8 suffix; // "KiB", "MiB", "GiB" .. e.t.c + DN_F64 bytes; +}; + +struct DN_FmtAppendResult +{ + DN_USize size_req; + DN_Str8 str8; + bool truncated; +}; + +struct DN_ProfilerAnchor +{ + // Inclusive refers to the time spent to complete the function call + // including all children functions. + // + // Exclusive refers to the time spent in the function, not including any + // time spent in children functions that we call that are also being + // profiled. If we recursively call into ourselves, the time we spent in + // our function is accumulated. + DN_U64 tsc_inclusive; + DN_U64 tsc_exclusive; + DN_U16 hit_count; + DN_Str8 name; +}; + +struct DN_ProfilerZone +{ + DN_U16 anchor_index; + DN_U64 begin_tsc; + DN_U16 parent_zone; + DN_U64 elapsed_tsc_at_zone_start; +}; + +struct DN_ProfilerAnchorArray +{ + DN_ProfilerAnchor *data; + DN_USize count; +}; + +typedef DN_U64 (DN_ProfilerTSCNowFunc)(); +struct DN_Profiler +{ + DN_USize frame_index; + DN_ProfilerAnchor *anchors; + DN_USize anchors_count; + DN_USize anchors_per_frame; + DN_U16 parent_zone; + bool paused; + DN_ProfilerTSCNowFunc *tsc_now; + DN_U64 tsc_frequency; + DN_ProfilerZone frame_zone; + DN_F64 frame_avg_tsc; +}; + +#if !defined(DN_STB_SPRINTF_HEADER_ONLY) + #define STB_SPRINTF_IMPLEMENTATION + #define STB_SPRINTF_STATIC +#endif + +DN_MSVC_WARNING_PUSH +DN_MSVC_WARNING_DISABLE(4505) // Unused function warning +DN_GCC_WARNING_PUSH +DN_GCC_WARNING_DISABLE(-Wunused-function) +// DN: Single header generator commented out this header => #include "../External/stb_sprintf.h" +// NOTE: Additional *unofficial* changes +// - Adding STBSP__ASAN to STBSP__PUBLICDEC so that MSVC's ASAN does not trigger (https://github.com/nothings/stb/pull/1350) +// - Adding __attribute__((no_sanitize("undefined"))) to STBSP__ASAN for CLANG so that UBSAN does not trigger (https://github.com/nothings/stb/pull/1477) +// - Adding '%S' for DN_Str8 +// - Using defined(__wasm64__) to correctly assign stbsp__uintptr to stbsp__uint64 for a 64bit WASM target. + +// stb_sprintf - v1.10 - public domain snprintf() implementation +// originally by Jeff Roberts / RAD Game Tools, 2015/10/20 +// http://github.com/nothings/stb +// +// allowed types: sc uidBboXx p AaGgEef n +// lengths : hh h ll j z t I64 I32 I +// +// Contributors: +// Fabian "ryg" Giesen (reformatting) +// github:aganm (attribute format) +// +// Contributors (bugfixes): +// github:d26435 +// github:trex78 +// github:account-login +// Jari Komppa (SI suffixes) +// Rohit Nirmal +// Marcin Wojdyr +// Leonard Ritter +// Stefano Zanotti +// Adam Allison +// Arvid Gerstmann +// Markus Kolb +// +// LICENSE: +// +// See end of file for license information. + +#ifndef STB_SPRINTF_H_INCLUDE +#define STB_SPRINTF_H_INCLUDE + +/* +Single file sprintf replacement. + +Originally written by Jeff Roberts at RAD Game Tools - 2015/10/20. +Hereby placed in public domain. + +This is a full sprintf replacement that supports everything that +the C runtime sprintfs support, including float/double, 64-bit integers, +hex floats, field parameters (%*.*d stuff), length reads backs, etc. + +Why would you need this if sprintf already exists? Well, first off, +it's *much* faster (see below). It's also much smaller than the CRT +versions code-space-wise. We've also added some simple improvements +that are super handy (commas in thousands, callbacks at buffer full, +for example). Finally, the format strings for MSVC and GCC differ +for 64-bit integers (among other small things), so this lets you use +the same format strings in cross platform code. + +It uses the standard single file trick of being both the header file +and the source itself. If you just include it normally, you just get +the header file function definitions. To get the code, you include +it from a C or C++ file and define STB_SPRINTF_IMPLEMENTATION first. + +It only uses va_args macros from the C runtime to do it's work. It +does cast doubles to S64s and shifts and divides U64s, which does +drag in CRT code on most platforms. + +It compiles to roughly 8K with float support, and 4K without. +As a comparison, when using MSVC static libs, calling sprintf drags +in 16K. + +API: +==== +int stbsp_sprintf( char * buf, char const * fmt, ... ) +int stbsp_snprintf( char * buf, int count, char const * fmt, ... ) + Convert an arg list into a buffer. stbsp_snprintf always returns + a zero-terminated string (unlike regular snprintf). + +int stbsp_vsprintf( char * buf, char const * fmt, va_list va ) +int stbsp_vsnprintf( char * buf, int count, char const * fmt, va_list va ) + Convert a va_list arg list into a buffer. stbsp_vsnprintf always returns + a zero-terminated string (unlike regular snprintf). + +int stbsp_vsprintfcb( STBSP_SPRINTFCB * callback, void * user, char * buf, char const * fmt, va_list va ) + typedef char * STBSP_SPRINTFCB( char const * buf, void * user, int len ); + Convert into a buffer, calling back every STB_SPRINTF_MIN chars. + Your callback can then copy the chars out, print them or whatever. + This function is actually the workhorse for everything else. + The buffer you pass in must hold at least STB_SPRINTF_MIN characters. + // you return the next buffer to use or 0 to stop converting + +void stbsp_set_separators( char comma, char period ) + Set the comma and period characters to use. + +FLOATS/DOUBLES: +=============== +This code uses a internal float->ascii conversion method that uses +doubles with error correction (double-doubles, for ~105 bits of +precision). This conversion is round-trip perfect - that is, an atof +of the values output here will give you the bit-exact double back. + +One difference is that our insignificant digits will be different than +with MSVC or GCC (but they don't match each other either). We also +don't attempt to find the minimum length matching float (pre-MSVC15 +doesn't either). + +If you don't need float or doubles at all, define STB_SPRINTF_NOFLOAT +and you'll save 4K of code space. + +64-BIT INTS: +============ +This library also supports 64-bit integers and you can use MSVC style or +GCC style indicators (%I64d or %lld). It supports the C99 specifiers +for size_t and ptr_diff_t (%jd %zd) as well. + +EXTRAS: +======= +Like some GCCs, for integers and floats, you can use a ' (single quote) +specifier and commas will be inserted on the thousands: "%'d" on 12345 +would print 12,345. + +For integers and floats, you can use a "$" specifier and the number +will be converted to float and then divided to get kilo, mega, giga or +tera and then printed, so "%$d" 1000 is "1.0 k", "%$.2d" 2536000 is +"2.53 M", etc. For byte values, use two $:s, like "%$$d" to turn +2536000 to "2.42 Mi". If you prefer JEDEC suffixes to SI ones, use three +$:s: "%$$$d" -> "2.42 M". To remove the space between the number and the +suffix, add "_" specifier: "%_$d" -> "2.53M". + +In addition to octal and hexadecimal conversions, you can print +integers in binary: "%b" for 256 would print 100. + +PERFORMANCE vs MSVC 2008 32-/64-bit (GCC is even slower than MSVC): +=================================================================== +"%d" across all 32-bit ints (4.8x/4.0x faster than 32-/64-bit MSVC) +"%24d" across all 32-bit ints (4.5x/4.2x faster) +"%x" across all 32-bit ints (4.5x/3.8x faster) +"%08x" across all 32-bit ints (4.3x/3.8x faster) +"%f" across e-10 to e+10 floats (7.3x/6.0x faster) +"%e" across e-10 to e+10 floats (8.1x/6.0x faster) +"%g" across e-10 to e+10 floats (10.0x/7.1x faster) +"%f" for values near e-300 (7.9x/6.5x faster) +"%f" for values near e+300 (10.0x/9.1x faster) +"%e" for values near e-300 (10.1x/7.0x faster) +"%e" for values near e+300 (9.2x/6.0x faster) +"%.320f" for values near e-300 (12.6x/11.2x faster) +"%a" for random values (8.6x/4.3x faster) +"%I64d" for 64-bits with 32-bit values (4.8x/3.4x faster) +"%I64d" for 64-bits > 32-bit values (4.9x/5.5x faster) +"%s%s%s" for 64 char strings (7.1x/7.3x faster) +"...512 char string..." ( 35.0x/32.5x faster!) +*/ + +#if defined(__clang__) + #if defined(__has_feature) && defined(__has_attribute) + #if __has_feature(address_sanitizer) + #if __has_attribute(__no_sanitize__) + #define STBSP__ASAN __attribute__((__no_sanitize__("address"))) + #elif __has_attribute(__no_sanitize_address__) + #define STBSP__ASAN __attribute__((__no_sanitize_address__)) + #elif __has_attribute(__no_address_safety_analysis__) + #define STBSP__ASAN __attribute__((__no_address_safety_analysis__)) + #endif + #endif + #endif +#elif defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) + #if defined(__SANITIZE_ADDRESS__) && __SANITIZE_ADDRESS__ + #define STBSP__ASAN __attribute__((__no_sanitize_address__)) + #endif +#elif defined(_MSC_VER) + #if defined(__SANITIZE_ADDRESS__) + #define STBSP__ASAN __declspec(no_sanitize_address) + #endif +#endif + +#ifndef STBSP__ASAN +#define STBSP__ASAN +#endif + +#ifdef STB_SPRINTF_STATIC +#define STBSP__PUBLICDEC static STBSP__ASAN +#define STBSP__PUBLICDEF static STBSP__ASAN +#else +#ifdef __cplusplus +#define STBSP__PUBLICDEC extern "C" STBSP__ASAN +#define STBSP__PUBLICDEF extern "C" STBSP__ASAN +#else +#define STBSP__PUBLICDEC extern STBSP__ASAN +#define STBSP__PUBLICDEF STBSP__ASAN +#endif +#endif + +#if defined(__has_attribute) + #if __has_attribute(format) + #define STBSP__ATTRIBUTE_FORMAT(fmt,va) __attribute__((format(printf,fmt,va))) + #endif +#endif + +#ifndef STBSP__ATTRIBUTE_FORMAT +#define STBSP__ATTRIBUTE_FORMAT(fmt,va) +#endif + +#ifdef _MSC_VER +#define STBSP__NOTUSED(v) (void)(v) +#else +#define STBSP__NOTUSED(v) (void)sizeof(v) +#endif + +#include // for va_arg(), va_list() +#include // size_t, ptrdiff_t + +#ifndef STB_SPRINTF_MIN +#define STB_SPRINTF_MIN 512 // how many characters per callback +#endif +typedef char *STBSP_SPRINTFCB(const char *buf, void *user, int len); + +#ifndef STB_SPRINTF_DECORATE +#define STB_SPRINTF_DECORATE(name) stbsp_##name // define this before including if you want to change the names +#endif + +STBSP__PUBLICDEC int STB_SPRINTF_DECORATE(vsprintf)(char *buf, char const *fmt, va_list va); +STBSP__PUBLICDEC int STB_SPRINTF_DECORATE(vsnprintf)(char *buf, int count, char const *fmt, va_list va); +STBSP__PUBLICDEC int STB_SPRINTF_DECORATE(sprintf)(char *buf, char const *fmt, ...) STBSP__ATTRIBUTE_FORMAT(2,3); +STBSP__PUBLICDEC int STB_SPRINTF_DECORATE(snprintf)(char *buf, int count, char const *fmt, ...) STBSP__ATTRIBUTE_FORMAT(3,4); + +STBSP__PUBLICDEC int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback, void *user, char *buf, char const *fmt, va_list va); +STBSP__PUBLICDEC void STB_SPRINTF_DECORATE(set_separators)(char comma, char period); + +#endif // STB_SPRINTF_H_INCLUDE + +#ifdef STB_SPRINTF_IMPLEMENTATION + +#define stbsp__uint32 unsigned int +#define stbsp__int32 signed int + +#ifdef _MSC_VER +#define stbsp__uint64 unsigned __int64 +#define stbsp__int64 signed __int64 +#else +#define stbsp__uint64 unsigned long long +#define stbsp__int64 signed long long +#endif +#define stbsp__uint16 unsigned short + +#ifndef stbsp__uintptr +#if defined(__ppc64__) || defined(__powerpc64__) || defined(__aarch64__) || defined(_M_X64) || defined(__x86_64__) || defined(__x86_64) || defined(__s390x__) || defined(__wasm64__) +#define stbsp__uintptr stbsp__uint64 +#else +#define stbsp__uintptr stbsp__uint32 +#endif +#endif + +#ifndef STB_SPRINTF_MSVC_MODE // used for MSVC2013 and earlier (MSVC2015 matches GCC) +#if defined(_MSC_VER) && (_MSC_VER < 1900) +#define STB_SPRINTF_MSVC_MODE +#endif +#endif + +#ifdef STB_SPRINTF_NOUNALIGNED // define this before inclusion to force stbsp_sprintf to always use aligned accesses +#define STBSP__UNALIGNED(code) +#else +#define STBSP__UNALIGNED(code) code +#endif + +#ifndef STB_SPRINTF_NOFLOAT +// internal float utility functions +static stbsp__int32 stbsp__real_to_str(char const **start, stbsp__uint32 *len, char *out, stbsp__int32 *decimal_pos, double value, stbsp__uint32 frac_digits); +static stbsp__int32 stbsp__real_to_parts(stbsp__int64 *bits, stbsp__int32 *expo, double value); +#define STBSP__SPECIAL 0x7000 +#endif + +static char stbsp__period = '.'; +static char stbsp__comma = ','; +static struct +{ + short temp; // force next field to be 2-byte aligned + char pair[201]; +} stbsp__digitpair = +{ + 0, + "00010203040506070809101112131415161718192021222324" + "25262728293031323334353637383940414243444546474849" + "50515253545556575859606162636465666768697071727374" + "75767778798081828384858687888990919293949596979899" +}; + +STBSP__PUBLICDEF void STB_SPRINTF_DECORATE(set_separators)(char pcomma, char pperiod) +{ + stbsp__period = pperiod; + stbsp__comma = pcomma; +} + +#define STBSP__LEFTJUST 1 +#define STBSP__LEADINGPLUS 2 +#define STBSP__LEADINGSPACE 4 +#define STBSP__LEADING_0X 8 +#define STBSP__LEADINGZERO 16 +#define STBSP__INTMAX 32 +#define STBSP__TRIPLET_COMMA 64 +#define STBSP__NEGATIVE 128 +#define STBSP__METRIC_SUFFIX 256 +#define STBSP__HALFWIDTH 512 +#define STBSP__METRIC_NOSPACE 1024 +#define STBSP__METRIC_1024 2048 +#define STBSP__METRIC_JEDEC 4096 + +static void stbsp__lead_sign(stbsp__uint32 fl, char *sign) +{ + sign[0] = 0; + if (fl & STBSP__NEGATIVE) { + sign[0] = 1; + sign[1] = '-'; + } else if (fl & STBSP__LEADINGSPACE) { + sign[0] = 1; + sign[1] = ' '; + } else if (fl & STBSP__LEADINGPLUS) { + sign[0] = 1; + sign[1] = '+'; + } +} + +static STBSP__ASAN stbsp__uint32 stbsp__strlen_limited(char const *s, stbsp__uint32 limit) +{ + char const * sn = s; + + // get up to 4-byte alignment + for (;;) { + if (((stbsp__uintptr)sn & 3) == 0) + break; + + if (!limit || *sn == 0) + return (stbsp__uint32)(sn - s); + + ++sn; + --limit; + } + + // scan over 4 bytes at a time to find terminating 0 + // this will intentionally scan up to 3 bytes past the end of buffers, + // but becase it works 4B aligned, it will never cross page boundaries + // (hence the STBSP__ASAN markup; the over-read here is intentional + // and harmless) + while (limit >= 4) { + stbsp__uint32 v = *(stbsp__uint32 *)sn; + // bit hack to find if there's a 0 byte in there + if ((v - 0x01010101) & (~v) & 0x80808080UL) + break; + + sn += 4; + limit -= 4; + } + + // handle the last few characters to find actual size + while (limit && *sn) { + ++sn; + --limit; + } + + return (stbsp__uint32)(sn - s); +} + +STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback, void *user, char *buf, char const *fmt, va_list va) +{ + static char hex[] = "0123456789abcdefxp"; + static char hexu[] = "0123456789ABCDEFXP"; + char *bf; + char const *f; + int tlen = 0; + + bf = buf; + f = fmt; + for (;;) { + stbsp__int32 fw, pr, tz; + stbsp__uint32 fl; + + // macros for the callback buffer stuff + #define stbsp__chk_cb_bufL(bytes) \ + { \ + int len = (int)(bf - buf); \ + if ((len + (bytes)) >= STB_SPRINTF_MIN) { \ + tlen += len; \ + if (0 == (bf = buf = callback(buf, user, len))) \ + goto done; \ + } \ + } + #define stbsp__chk_cb_buf(bytes) \ + { \ + if (callback) { \ + stbsp__chk_cb_bufL(bytes); \ + } \ + } + #define stbsp__flush_cb() \ + { \ + stbsp__chk_cb_bufL(STB_SPRINTF_MIN - 1); \ + } // flush if there is even one byte in the buffer + #define stbsp__cb_buf_clamp(cl, v) \ + cl = v; \ + if (callback) { \ + int lg = STB_SPRINTF_MIN - (int)(bf - buf); \ + if (cl > lg) \ + cl = lg; \ + } + + // fast copy everything up to the next % (or end of string) + for (;;) { + while (((stbsp__uintptr)f) & 3) { + schk1: + if (f[0] == '%') + goto scandd; + schk2: + if (f[0] == 0) + goto endfmt; + stbsp__chk_cb_buf(1); + *bf++ = f[0]; + ++f; + } + for (;;) { + // Check if the next 4 bytes contain %(0x25) or end of string. + // Using the 'hasless' trick: + // https://graphics.stanford.edu/~seander/bithacks.html#HasLessInWord + stbsp__uint32 v, c; + v = *(stbsp__uint32 *)f; + c = (~v) & 0x80808080; + if (((v ^ 0x25252525) - 0x01010101) & c) + goto schk1; + if ((v - 0x01010101) & c) + goto schk2; + if (callback) + if ((STB_SPRINTF_MIN - (int)(bf - buf)) < 4) + goto schk1; + #ifdef STB_SPRINTF_NOUNALIGNED + if(((stbsp__uintptr)bf) & 3) { + bf[0] = f[0]; + bf[1] = f[1]; + bf[2] = f[2]; + bf[3] = f[3]; + } else + #endif + { + *(stbsp__uint32 *)bf = v; + } + bf += 4; + f += 4; + } + } + scandd: + + ++f; + + // ok, we have a percent, read the modifiers first + fw = 0; + pr = -1; + fl = 0; + tz = 0; + + // flags + for (;;) { + switch (f[0]) { + // if we have left justify + case '-': + fl |= STBSP__LEFTJUST; + ++f; + continue; + // if we have leading plus + case '+': + fl |= STBSP__LEADINGPLUS; + ++f; + continue; + // if we have leading space + case ' ': + fl |= STBSP__LEADINGSPACE; + ++f; + continue; + // if we have leading 0x + case '#': + fl |= STBSP__LEADING_0X; + ++f; + continue; + // if we have thousand commas + case '\'': + fl |= STBSP__TRIPLET_COMMA; + ++f; + continue; + // if we have kilo marker (none->kilo->kibi->jedec) + case '$': + if (fl & STBSP__METRIC_SUFFIX) { + if (fl & STBSP__METRIC_1024) { + fl |= STBSP__METRIC_JEDEC; + } else { + fl |= STBSP__METRIC_1024; + } + } else { + fl |= STBSP__METRIC_SUFFIX; + } + ++f; + continue; + // if we don't want space between metric suffix and number + case '_': + fl |= STBSP__METRIC_NOSPACE; + ++f; + continue; + // if we have leading zero + case '0': + fl |= STBSP__LEADINGZERO; + ++f; + goto flags_done; + default: goto flags_done; + } + } + flags_done: + + // get the field width + if (f[0] == '*') { + fw = va_arg(va, stbsp__uint32); + ++f; + } else { + while ((f[0] >= '0') && (f[0] <= '9')) { + fw = fw * 10 + f[0] - '0'; + f++; + } + } + // get the precision + if (f[0] == '.') { + ++f; + if (f[0] == '*') { + pr = va_arg(va, stbsp__uint32); + ++f; + } else { + pr = 0; + while ((f[0] >= '0') && (f[0] <= '9')) { + pr = pr * 10 + f[0] - '0'; + f++; + } + } + } + + // handle integer size overrides + switch (f[0]) { + // are we halfwidth? + case 'h': + fl |= STBSP__HALFWIDTH; + ++f; + if (f[0] == 'h') + ++f; // QUARTERWIDTH + break; + // are we 64-bit (unix style) + case 'l': + fl |= ((sizeof(long) == 8) ? STBSP__INTMAX : 0); + ++f; + if (f[0] == 'l') { + fl |= STBSP__INTMAX; + ++f; + } + break; + // are we 64-bit on intmax? (c99) + case 'j': + fl |= (sizeof(size_t) == 8) ? STBSP__INTMAX : 0; + ++f; + break; + // are we 64-bit on size_t or ptrdiff_t? (c99) + case 'z': + fl |= (sizeof(ptrdiff_t) == 8) ? STBSP__INTMAX : 0; + ++f; + break; + case 't': + fl |= (sizeof(ptrdiff_t) == 8) ? STBSP__INTMAX : 0; + ++f; + break; + // are we 64-bit (msft style) + case 'I': + if ((f[1] == '6') && (f[2] == '4')) { + fl |= STBSP__INTMAX; + f += 3; + } else if ((f[1] == '3') && (f[2] == '2')) { + f += 3; + } else { + fl |= ((sizeof(void *) == 8) ? STBSP__INTMAX : 0); + ++f; + } + break; + default: break; + } + + // handle each replacement + switch (f[0]) { + #define STBSP__NUMSZ 512 // big enough for e308 (with commas) or e-307 + char num[STBSP__NUMSZ]; + char lead[8]; + char tail[8]; + char *s; + char const *h; + stbsp__uint32 l, n, cs; + stbsp__uint64 n64; +#ifndef STB_SPRINTF_NOFLOAT + double fv; +#endif + stbsp__int32 dp; + char const *sn; + + case 's': + // get the string + s = va_arg(va, char *); + if (s == 0) + s = (char *)"null"; + // get the length, limited to desired precision + // always limit to ~0u chars since our counts are 32b + l = stbsp__strlen_limited(s, (pr >= 0) ? pr : ~0u); + lead[0] = 0; + tail[0] = 0; + pr = 0; + dp = 0; + cs = 0; + // copy the string in + goto scopy; + + case 'S': + { + DN_Str8 str8 = va_arg(va, DN_Str8); + s = (char *)str8.data; + l = (uint32_t)str8.size; + lead[0] = 0; + tail[0] = 0; + pr = 0; + dp = 0; + cs = 0; + }goto scopy; + + case 'c': // char + // get the character + s = num + STBSP__NUMSZ - 1; + *s = (char)va_arg(va, int); + l = 1; + lead[0] = 0; + tail[0] = 0; + pr = 0; + dp = 0; + cs = 0; + goto scopy; + + case 'n': // weird write-bytes specifier + { + int *d = va_arg(va, int *); + *d = tlen + (int)(bf - buf); + } break; + +#ifdef STB_SPRINTF_NOFLOAT + case 'A': // float + case 'a': // hex float + case 'G': // float + case 'g': // float + case 'E': // float + case 'e': // float + case 'f': // float + va_arg(va, double); // eat it + s = (char *)"No float"; + l = 8; + lead[0] = 0; + tail[0] = 0; + pr = 0; + cs = 0; + STBSP__NOTUSED(dp); + goto scopy; +#else + case 'A': // hex float + case 'a': // hex float + h = (f[0] == 'A') ? hexu : hex; + fv = va_arg(va, double); + if (pr == -1) + pr = 6; // default is 6 + // read the double into a string + if (stbsp__real_to_parts((stbsp__int64 *)&n64, &dp, fv)) + fl |= STBSP__NEGATIVE; + + s = num + 64; + + stbsp__lead_sign(fl, lead); + + if (dp == -1023) + dp = (n64) ? -1022 : 0; + else + n64 |= (((stbsp__uint64)1) << 52); + n64 <<= (64 - 56); + if (pr < 15) + n64 += ((((stbsp__uint64)8) << 56) >> (pr * 4)); +// add leading chars + +#ifdef STB_SPRINTF_MSVC_MODE + *s++ = '0'; + *s++ = 'x'; +#else + lead[1 + lead[0]] = '0'; + lead[2 + lead[0]] = 'x'; + lead[0] += 2; +#endif + *s++ = h[(n64 >> 60) & 15]; + n64 <<= 4; + if (pr) + *s++ = stbsp__period; + sn = s; + + // print the bits + n = pr; + if (n > 13) + n = 13; + if (pr > (stbsp__int32)n) + tz = pr - n; + pr = 0; + while (n--) { + *s++ = h[(n64 >> 60) & 15]; + n64 <<= 4; + } + + // print the expo + tail[1] = h[17]; + if (dp < 0) { + tail[2] = '-'; + dp = -dp; + } else + tail[2] = '+'; + n = (dp >= 1000) ? 6 : ((dp >= 100) ? 5 : ((dp >= 10) ? 4 : 3)); + tail[0] = (char)n; + for (;;) { + tail[n] = '0' + dp % 10; + if (n <= 3) + break; + --n; + dp /= 10; + } + + dp = (int)(s - sn); + l = (int)(s - (num + 64)); + s = num + 64; + cs = 1 + (3 << 24); + goto scopy; + + case 'G': // float + case 'g': // float + h = (f[0] == 'G') ? hexu : hex; + fv = va_arg(va, double); + if (pr == -1) + pr = 6; + else if (pr == 0) + pr = 1; // default is 6 + // read the double into a string + if (stbsp__real_to_str(&sn, &l, num, &dp, fv, (pr - 1) | 0x80000000)) + fl |= STBSP__NEGATIVE; + + // clamp the precision and delete extra zeros after clamp + n = pr; + if (l > (stbsp__uint32)pr) + l = pr; + while ((l > 1) && (pr) && (sn[l - 1] == '0')) { + --pr; + --l; + } + + // should we use %e + if ((dp <= -4) || (dp > (stbsp__int32)n)) { + if (pr > (stbsp__int32)l) + pr = l - 1; + else if (pr) + --pr; // when using %e, there is one digit before the decimal + goto doexpfromg; + } + // this is the insane action to get the pr to match %g semantics for %f + if (dp > 0) { + pr = (dp < (stbsp__int32)l) ? l - dp : 0; + } else { + pr = -dp + ((pr > (stbsp__int32)l) ? (stbsp__int32) l : pr); + } + goto dofloatfromg; + + case 'E': // float + case 'e': // float + h = (f[0] == 'E') ? hexu : hex; + fv = va_arg(va, double); + if (pr == -1) + pr = 6; // default is 6 + // read the double into a string + if (stbsp__real_to_str(&sn, &l, num, &dp, fv, pr | 0x80000000)) + fl |= STBSP__NEGATIVE; + doexpfromg: + tail[0] = 0; + stbsp__lead_sign(fl, lead); + if (dp == STBSP__SPECIAL) { + s = (char *)sn; + cs = 0; + pr = 0; + goto scopy; + } + s = num + 64; + // handle leading chars + *s++ = sn[0]; + + if (pr) + *s++ = stbsp__period; + + // handle after decimal + if ((l - 1) > (stbsp__uint32)pr) + l = pr + 1; + for (n = 1; n < l; n++) + *s++ = sn[n]; + // trailing zeros + tz = pr - (l - 1); + pr = 0; + // dump expo + tail[1] = h[0xe]; + dp -= 1; + if (dp < 0) { + tail[2] = '-'; + dp = -dp; + } else + tail[2] = '+'; +#ifdef STB_SPRINTF_MSVC_MODE + n = 5; +#else + n = (dp >= 100) ? 5 : 4; +#endif + tail[0] = (char)n; + for (;;) { + tail[n] = '0' + dp % 10; + if (n <= 3) + break; + --n; + dp /= 10; + } + cs = 1 + (3 << 24); // how many tens + goto flt_lead; + + case 'f': // float + fv = va_arg(va, double); + doafloat: + // do kilos + if (fl & STBSP__METRIC_SUFFIX) { + double divisor; + divisor = 1000.0f; + if (fl & STBSP__METRIC_1024) + divisor = 1024.0; + while (fl < 0x4000000) { + if ((fv < divisor) && (fv > -divisor)) + break; + fv /= divisor; + fl += 0x1000000; + } + } + if (pr == -1) + pr = 6; // default is 6 + // read the double into a string + if (stbsp__real_to_str(&sn, &l, num, &dp, fv, pr)) + fl |= STBSP__NEGATIVE; + dofloatfromg: + tail[0] = 0; + stbsp__lead_sign(fl, lead); + if (dp == STBSP__SPECIAL) { + s = (char *)sn; + cs = 0; + pr = 0; + goto scopy; + } + s = num + 64; + + // handle the three decimal varieties + if (dp <= 0) { + stbsp__int32 i; + // handle 0.000*000xxxx + *s++ = '0'; + if (pr) + *s++ = stbsp__period; + n = -dp; + if ((stbsp__int32)n > pr) + n = pr; + i = n; + while (i) { + if ((((stbsp__uintptr)s) & 3) == 0) + break; + *s++ = '0'; + --i; + } + while (i >= 4) { + *(stbsp__uint32 *)s = 0x30303030; + s += 4; + i -= 4; + } + while (i) { + *s++ = '0'; + --i; + } + if ((stbsp__int32)(l + n) > pr) + l = pr - n; + i = l; + while (i) { + *s++ = *sn++; + --i; + } + tz = pr - (n + l); + cs = 1 + (3 << 24); // how many tens did we write (for commas below) + } else { + cs = (fl & STBSP__TRIPLET_COMMA) ? ((600 - (stbsp__uint32)dp) % 3) : 0; + if ((stbsp__uint32)dp >= l) { + // handle xxxx000*000.0 + n = 0; + for (;;) { + if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) { + cs = 0; + *s++ = stbsp__comma; + } else { + *s++ = sn[n]; + ++n; + if (n >= l) + break; + } + } + if (n < (stbsp__uint32)dp) { + n = dp - n; + if ((fl & STBSP__TRIPLET_COMMA) == 0) { + while (n) { + if ((((stbsp__uintptr)s) & 3) == 0) + break; + *s++ = '0'; + --n; + } + while (n >= 4) { + *(stbsp__uint32 *)s = 0x30303030; + s += 4; + n -= 4; + } + } + while (n) { + if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) { + cs = 0; + *s++ = stbsp__comma; + } else { + *s++ = '0'; + --n; + } + } + } + cs = (int)(s - (num + 64)) + (3 << 24); // cs is how many tens + if (pr) { + *s++ = stbsp__period; + tz = pr; + } + } else { + // handle xxxxx.xxxx000*000 + n = 0; + for (;;) { + if ((fl & STBSP__TRIPLET_COMMA) && (++cs == 4)) { + cs = 0; + *s++ = stbsp__comma; + } else { + *s++ = sn[n]; + ++n; + if (n >= (stbsp__uint32)dp) + break; + } + } + cs = (int)(s - (num + 64)) + (3 << 24); // cs is how many tens + if (pr) + *s++ = stbsp__period; + if ((l - dp) > (stbsp__uint32)pr) + l = pr + dp; + while (n < l) { + *s++ = sn[n]; + ++n; + } + tz = pr - (l - dp); + } + } + pr = 0; + + // handle k,m,g,t + if (fl & STBSP__METRIC_SUFFIX) { + char idx; + idx = 1; + if (fl & STBSP__METRIC_NOSPACE) + idx = 0; + tail[0] = idx; + tail[1] = ' '; + { + if (fl >> 24) { // SI kilo is 'k', JEDEC and SI kibits are 'K'. + if (fl & STBSP__METRIC_1024) + tail[idx + 1] = "_KMGT"[fl >> 24]; + else + tail[idx + 1] = "_kMGT"[fl >> 24]; + idx++; + // If printing kibits and not in jedec, add the 'i'. + if (fl & STBSP__METRIC_1024 && !(fl & STBSP__METRIC_JEDEC)) { + tail[idx + 1] = 'i'; + idx++; + } + tail[0] = idx; + } + } + }; + + flt_lead: + // get the length that we copied + l = (stbsp__uint32)(s - (num + 64)); + s = num + 64; + goto scopy; +#endif + + case 'B': // upper binary + case 'b': // lower binary + h = (f[0] == 'B') ? hexu : hex; + lead[0] = 0; + if (fl & STBSP__LEADING_0X) { + lead[0] = 2; + lead[1] = '0'; + lead[2] = h[0xb]; + } + l = (8 << 4) | (1 << 8); + goto radixnum; + + case 'o': // octal + h = hexu; + lead[0] = 0; + if (fl & STBSP__LEADING_0X) { + lead[0] = 1; + lead[1] = '0'; + } + l = (3 << 4) | (3 << 8); + goto radixnum; + + case 'p': // pointer + fl |= (sizeof(void *) == 8) ? STBSP__INTMAX : 0; + pr = sizeof(void *) * 2; + fl &= ~STBSP__LEADINGZERO; // 'p' only prints the pointer with zeros + // fall through - to X + + case 'X': // upper hex + case 'x': // lower hex + h = (f[0] == 'X') ? hexu : hex; + l = (4 << 4) | (4 << 8); + lead[0] = 0; + if (fl & STBSP__LEADING_0X) { + lead[0] = 2; + lead[1] = '0'; + lead[2] = h[16]; + } + radixnum: + // get the number + if (fl & STBSP__INTMAX) + n64 = va_arg(va, stbsp__uint64); + else + n64 = va_arg(va, stbsp__uint32); + + s = num + STBSP__NUMSZ; + dp = 0; + // clear tail, and clear leading if value is zero + tail[0] = 0; + if (n64 == 0) { + lead[0] = 0; + if (pr == 0) { + l = 0; + cs = 0; + goto scopy; + } + } + // convert to string + for (;;) { + *--s = h[n64 & ((1 << (l >> 8)) - 1)]; + n64 >>= (l >> 8); + if (!((n64) || ((stbsp__int32)((num + STBSP__NUMSZ) - s) < pr))) + break; + if (fl & STBSP__TRIPLET_COMMA) { + ++l; + if ((l & 15) == ((l >> 4) & 15)) { + l &= ~15; + *--s = stbsp__comma; + } + } + }; + // get the tens and the comma pos + cs = (stbsp__uint32)((num + STBSP__NUMSZ) - s) + ((((l >> 4) & 15)) << 24); + // get the length that we copied + l = (stbsp__uint32)((num + STBSP__NUMSZ) - s); + // copy it + goto scopy; + + case 'u': // unsigned + case 'i': + case 'd': // integer + // get the integer and abs it + if (fl & STBSP__INTMAX) { + stbsp__int64 i64 = va_arg(va, stbsp__int64); + n64 = (stbsp__uint64)i64; + if ((f[0] != 'u') && (i64 < 0)) { + n64 = (stbsp__uint64)-i64; + fl |= STBSP__NEGATIVE; + } + } else { + stbsp__int32 i = va_arg(va, stbsp__int32); + n64 = (stbsp__uint32)i; + if ((f[0] != 'u') && (i < 0)) { + n64 = (stbsp__uint32)-i; + fl |= STBSP__NEGATIVE; + } + } + +#ifndef STB_SPRINTF_NOFLOAT + if (fl & STBSP__METRIC_SUFFIX) { + if (n64 < 1024) + pr = 0; + else if (pr == -1) + pr = 1; + fv = (double)(stbsp__int64)n64; + goto doafloat; + } +#endif + + // convert to string + s = num + STBSP__NUMSZ; + l = 0; + + for (;;) { + // do in 32-bit chunks (avoid lots of 64-bit divides even with constant denominators) + char *o = s - 8; + if (n64 >= 100000000) { + n = (stbsp__uint32)(n64 % 100000000); + n64 /= 100000000; + } else { + n = (stbsp__uint32)n64; + n64 = 0; + } + if ((fl & STBSP__TRIPLET_COMMA) == 0) { + do { + s -= 2; + *(stbsp__uint16 *)s = *(stbsp__uint16 *)&stbsp__digitpair.pair[(n % 100) * 2]; + n /= 100; + } while (n); + } + while (n) { + if ((fl & STBSP__TRIPLET_COMMA) && (l++ == 3)) { + l = 0; + *--s = stbsp__comma; + --o; + } else { + *--s = (char)(n % 10) + '0'; + n /= 10; + } + } + if (n64 == 0) { + if ((s[0] == '0') && (s != (num + STBSP__NUMSZ))) + ++s; + break; + } + while (s != o) + if ((fl & STBSP__TRIPLET_COMMA) && (l++ == 3)) { + l = 0; + *--s = stbsp__comma; + --o; + } else { + *--s = '0'; + } + } + + tail[0] = 0; + stbsp__lead_sign(fl, lead); + + // get the length that we copied + l = (stbsp__uint32)((num + STBSP__NUMSZ) - s); + if (l == 0) { + *--s = '0'; + l = 1; + } + cs = l + (3 << 24); + if (pr < 0) + pr = 0; + + scopy: + // get fw=leading/trailing space, pr=leading zeros + if (pr < (stbsp__int32)l) + pr = l; + n = pr + lead[0] + tail[0] + tz; + if (fw < (stbsp__int32)n) + fw = n; + fw -= n; + pr -= l; + + // handle right justify and leading zeros + if ((fl & STBSP__LEFTJUST) == 0) { + if (fl & STBSP__LEADINGZERO) // if leading zeros, everything is in pr + { + pr = (fw > pr) ? fw : pr; + fw = 0; + } else { + fl &= ~STBSP__TRIPLET_COMMA; // if no leading zeros, then no commas + } + } + + // copy the spaces and/or zeros + if (fw + pr) { + stbsp__int32 i; + stbsp__uint32 c; + + // copy leading spaces (or when doing %8.4d stuff) + if ((fl & STBSP__LEFTJUST) == 0) + while (fw > 0) { + stbsp__cb_buf_clamp(i, fw); + fw -= i; + while (i) { + if ((((stbsp__uintptr)bf) & 3) == 0) + break; + *bf++ = ' '; + --i; + } + while (i >= 4) { + *(stbsp__uint32 *)bf = 0x20202020; + bf += 4; + i -= 4; + } + while (i) { + *bf++ = ' '; + --i; + } + stbsp__chk_cb_buf(1); + } + + // copy leader + sn = lead + 1; + while (lead[0]) { + stbsp__cb_buf_clamp(i, lead[0]); + lead[0] -= (char)i; + while (i) { + *bf++ = *sn++; + --i; + } + stbsp__chk_cb_buf(1); + } + + // copy leading zeros + c = cs >> 24; + cs &= 0xffffff; + cs = (fl & STBSP__TRIPLET_COMMA) ? ((stbsp__uint32)(c - ((pr + cs) % (c + 1)))) : 0; + while (pr > 0) { + stbsp__cb_buf_clamp(i, pr); + pr -= i; + if ((fl & STBSP__TRIPLET_COMMA) == 0) { + while (i) { + if ((((stbsp__uintptr)bf) & 3) == 0) + break; + *bf++ = '0'; + --i; + } + while (i >= 4) { + *(stbsp__uint32 *)bf = 0x30303030; + bf += 4; + i -= 4; + } + } + while (i) { + if ((fl & STBSP__TRIPLET_COMMA) && (cs++ == c)) { + cs = 0; + *bf++ = stbsp__comma; + } else + *bf++ = '0'; + --i; + } + stbsp__chk_cb_buf(1); + } + } + + // copy leader if there is still one + sn = lead + 1; + while (lead[0]) { + stbsp__int32 i; + stbsp__cb_buf_clamp(i, lead[0]); + lead[0] -= (char)i; + while (i) { + *bf++ = *sn++; + --i; + } + stbsp__chk_cb_buf(1); + } + + // copy the string + n = l; + while (n) { + stbsp__int32 i; + stbsp__cb_buf_clamp(i, n); + n -= i; + STBSP__UNALIGNED(while (i >= 4) { + *(stbsp__uint32 volatile *)bf = *(stbsp__uint32 volatile *)s; + bf += 4; + s += 4; + i -= 4; + }) + while (i) { + *bf++ = *s++; + --i; + } + stbsp__chk_cb_buf(1); + } + + // copy trailing zeros + while (tz) { + stbsp__int32 i; + stbsp__cb_buf_clamp(i, tz); + tz -= i; + while (i) { + if ((((stbsp__uintptr)bf) & 3) == 0) + break; + *bf++ = '0'; + --i; + } + while (i >= 4) { + *(stbsp__uint32 *)bf = 0x30303030; + bf += 4; + i -= 4; + } + while (i) { + *bf++ = '0'; + --i; + } + stbsp__chk_cb_buf(1); + } + + // copy tail if there is one + sn = tail + 1; + while (tail[0]) { + stbsp__int32 i; + stbsp__cb_buf_clamp(i, tail[0]); + tail[0] -= (char)i; + while (i) { + *bf++ = *sn++; + --i; + } + stbsp__chk_cb_buf(1); + } + + // handle the left justify + if (fl & STBSP__LEFTJUST) + if (fw > 0) { + while (fw) { + stbsp__int32 i; + stbsp__cb_buf_clamp(i, fw); + fw -= i; + while (i) { + if ((((stbsp__uintptr)bf) & 3) == 0) + break; + *bf++ = ' '; + --i; + } + while (i >= 4) { + *(stbsp__uint32 *)bf = 0x20202020; + bf += 4; + i -= 4; + } + while (i--) + *bf++ = ' '; + stbsp__chk_cb_buf(1); + } + } + break; + + default: // unknown, just copy code + s = num + STBSP__NUMSZ - 1; + *s = f[0]; + l = 1; + fw = fl = 0; + lead[0] = 0; + tail[0] = 0; + pr = 0; + dp = 0; + cs = 0; + goto scopy; + } + ++f; + } +endfmt: + + if (!callback) + *bf = 0; + else + stbsp__flush_cb(); + +done: + return tlen + (int)(bf - buf); +} + +// cleanup +#undef STBSP__LEFTJUST +#undef STBSP__LEADINGPLUS +#undef STBSP__LEADINGSPACE +#undef STBSP__LEADING_0X +#undef STBSP__LEADINGZERO +#undef STBSP__INTMAX +#undef STBSP__TRIPLET_COMMA +#undef STBSP__NEGATIVE +#undef STBSP__METRIC_SUFFIX +#undef STBSP__NUMSZ +#undef stbsp__chk_cb_bufL +#undef stbsp__chk_cb_buf +#undef stbsp__flush_cb +#undef stbsp__cb_buf_clamp + +// ============================================================================ +// wrapper functions + +STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(sprintf)(char *buf, char const *fmt, ...) +{ + int result; + va_list va; + va_start(va, fmt); + result = STB_SPRINTF_DECORATE(vsprintfcb)(0, 0, buf, fmt, va); + va_end(va); + return result; +} + +typedef struct stbsp__context { + char *buf; + int count; + int length; + char tmp[STB_SPRINTF_MIN]; +} stbsp__context; + +static char *stbsp__clamp_callback(const char *buf, void *user, int len) +{ + stbsp__context *c = (stbsp__context *)user; + c->length += len; + + if (len > c->count) + len = c->count; + + if (len) { + if (buf != c->buf) { + const char *s, *se; + char *d; + d = c->buf; + s = buf; + se = buf + len; + do { + *d++ = *s++; + } while (s < se); + } + c->buf += len; + c->count -= len; + } + + if (c->count <= 0) + return c->tmp; + return (c->count >= STB_SPRINTF_MIN) ? c->buf : c->tmp; // go direct into buffer if you can +} + +static char * stbsp__count_clamp_callback( const char * buf, void * user, int len ) +{ + stbsp__context * c = (stbsp__context*)user; + (void) sizeof(buf); + + c->length += len; + return c->tmp; // go direct into buffer if you can +} + +STBSP__PUBLICDEF int STB_SPRINTF_DECORATE( vsnprintf )( char * buf, int count, char const * fmt, va_list va ) +{ + stbsp__context c; + + if ( (count == 0) && !buf ) + { + c.length = 0; + + STB_SPRINTF_DECORATE( vsprintfcb )( stbsp__count_clamp_callback, &c, c.tmp, fmt, va ); + } + else + { + int l; + + c.buf = buf; + c.count = count; + c.length = 0; + + STB_SPRINTF_DECORATE( vsprintfcb )( stbsp__clamp_callback, &c, stbsp__clamp_callback(0,&c,0), fmt, va ); + + // zero-terminate + l = (int)( c.buf - buf ); + if ( l >= count ) // should never be greater, only equal (or less) than count + l = count - 1; + buf[l] = 0; + } + + return c.length; +} + +STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(snprintf)(char *buf, int count, char const *fmt, ...) +{ + int result; + va_list va; + va_start(va, fmt); + + result = STB_SPRINTF_DECORATE(vsnprintf)(buf, count, fmt, va); + va_end(va); + + return result; +} + +STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintf)(char *buf, char const *fmt, va_list va) +{ + return STB_SPRINTF_DECORATE(vsprintfcb)(0, 0, buf, fmt, va); +} + +// ======================================================================= +// low level float utility functions + +#ifndef STB_SPRINTF_NOFLOAT + +// copies d to bits w/ strict aliasing (this compiles to nothing on /Ox) +#define STBSP__COPYFP(dest, src) \ + { \ + int cn; \ + for (cn = 0; cn < 8; cn++) \ + ((char *)&dest)[cn] = ((char *)&src)[cn]; \ + } + +// get float info +static stbsp__int32 stbsp__real_to_parts(stbsp__int64 *bits, stbsp__int32 *expo, double value) +{ + double d; + stbsp__int64 b = 0; + + // load value and round at the frac_digits + d = value; + + STBSP__COPYFP(b, d); + + *bits = b & ((((stbsp__uint64)1) << 52) - 1); + *expo = (stbsp__int32)(((b >> 52) & 2047) - 1023); + + return (stbsp__int32)((stbsp__uint64) b >> 63); +} + +static double const stbsp__bot[23] = { + 1e+000, 1e+001, 1e+002, 1e+003, 1e+004, 1e+005, 1e+006, 1e+007, 1e+008, 1e+009, 1e+010, 1e+011, + 1e+012, 1e+013, 1e+014, 1e+015, 1e+016, 1e+017, 1e+018, 1e+019, 1e+020, 1e+021, 1e+022 +}; +static double const stbsp__negbot[22] = { + 1e-001, 1e-002, 1e-003, 1e-004, 1e-005, 1e-006, 1e-007, 1e-008, 1e-009, 1e-010, 1e-011, + 1e-012, 1e-013, 1e-014, 1e-015, 1e-016, 1e-017, 1e-018, 1e-019, 1e-020, 1e-021, 1e-022 +}; +static double const stbsp__negboterr[22] = { + -5.551115123125783e-018, -2.0816681711721684e-019, -2.0816681711721686e-020, -4.7921736023859299e-021, -8.1803053914031305e-022, 4.5251888174113741e-023, + 4.5251888174113739e-024, -2.0922560830128471e-025, -6.2281591457779853e-026, -3.6432197315497743e-027, 6.0503030718060191e-028, 2.0113352370744385e-029, + -3.0373745563400371e-030, 1.1806906454401013e-032, -7.7705399876661076e-032, 2.0902213275965398e-033, -7.1542424054621921e-034, -7.1542424054621926e-035, + 2.4754073164739869e-036, 5.4846728545790429e-037, 9.2462547772103625e-038, -4.8596774326570872e-039 +}; +static double const stbsp__top[13] = { + 1e+023, 1e+046, 1e+069, 1e+092, 1e+115, 1e+138, 1e+161, 1e+184, 1e+207, 1e+230, 1e+253, 1e+276, 1e+299 +}; +static double const stbsp__negtop[13] = { + 1e-023, 1e-046, 1e-069, 1e-092, 1e-115, 1e-138, 1e-161, 1e-184, 1e-207, 1e-230, 1e-253, 1e-276, 1e-299 +}; +static double const stbsp__toperr[13] = { + 8388608, + 6.8601809640529717e+028, + -7.253143638152921e+052, + -4.3377296974619174e+075, + -1.5559416129466825e+098, + -3.2841562489204913e+121, + -3.7745893248228135e+144, + -1.7356668416969134e+167, + -3.8893577551088374e+190, + -9.9566444326005119e+213, + 6.3641293062232429e+236, + -5.2069140800249813e+259, + -5.2504760255204387e+282 +}; +static double const stbsp__negtoperr[13] = { + 3.9565301985100693e-040, -2.299904345391321e-063, 3.6506201437945798e-086, 1.1875228833981544e-109, + -5.0644902316928607e-132, -6.7156837247865426e-155, -2.812077463003139e-178, -5.7778912386589953e-201, + 7.4997100559334532e-224, -4.6439668915134491e-247, -6.3691100762962136e-270, -9.436808465446358e-293, + 8.0970921678014997e-317 +}; + +#if defined(_MSC_VER) && (_MSC_VER <= 1200) +static stbsp__uint64 const stbsp__powten[20] = { + 1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, + 10000000000, + 100000000000, + 1000000000000, + 10000000000000, + 100000000000000, + 1000000000000000, + 10000000000000000, + 100000000000000000, + 1000000000000000000, + 10000000000000000000U +}; +#define stbsp__tento19th ((stbsp__uint64)1000000000000000000) +#else +static stbsp__uint64 const stbsp__powten[20] = { + 1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, + 10000000000ULL, + 100000000000ULL, + 1000000000000ULL, + 10000000000000ULL, + 100000000000000ULL, + 1000000000000000ULL, + 10000000000000000ULL, + 100000000000000000ULL, + 1000000000000000000ULL, + 10000000000000000000ULL +}; +#define stbsp__tento19th (1000000000000000000ULL) +#endif + +#define stbsp__ddmulthi(oh, ol, xh, yh) \ + { \ + double ahi = 0, alo, bhi = 0, blo; \ + stbsp__int64 bt; \ + oh = xh * yh; \ + STBSP__COPYFP(bt, xh); \ + bt &= ((~(stbsp__uint64)0) << 27); \ + STBSP__COPYFP(ahi, bt); \ + alo = xh - ahi; \ + STBSP__COPYFP(bt, yh); \ + bt &= ((~(stbsp__uint64)0) << 27); \ + STBSP__COPYFP(bhi, bt); \ + blo = yh - bhi; \ + ol = ((ahi * bhi - oh) + ahi * blo + alo * bhi) + alo * blo; \ + } + +#define stbsp__ddtoS64(ob, xh, xl) \ + { \ + double ahi = 0, alo, vh, t; \ + ob = (stbsp__int64)xh; \ + vh = (double)ob; \ + ahi = (xh - vh); \ + t = (ahi - xh); \ + alo = (xh - (ahi - t)) - (vh + t); \ + ob += (stbsp__int64)(ahi + alo + xl); \ + } + +#define stbsp__ddrenorm(oh, ol) \ + { \ + double s; \ + s = oh + ol; \ + ol = ol - (s - oh); \ + oh = s; \ + } + +#define stbsp__ddmultlo(oh, ol, xh, xl, yh, yl) ol = ol + (xh * yl + xl * yh); + +#define stbsp__ddmultlos(oh, ol, xh, yl) ol = ol + (xh * yl); + +static void stbsp__raise_to_power10(double *ohi, double *olo, double d, stbsp__int32 power) // power can be -323 to +350 +{ + double ph, pl; + if ((power >= 0) && (power <= 22)) { + stbsp__ddmulthi(ph, pl, d, stbsp__bot[power]); + } else { + stbsp__int32 e, et, eb; + double p2h, p2l; + + e = power; + if (power < 0) + e = -e; + et = (e * 0x2c9) >> 14; /* %23 */ + if (et > 13) + et = 13; + eb = e - (et * 23); + + ph = d; + pl = 0.0; + if (power < 0) { + if (eb) { + --eb; + stbsp__ddmulthi(ph, pl, d, stbsp__negbot[eb]); + stbsp__ddmultlos(ph, pl, d, stbsp__negboterr[eb]); + } + if (et) { + stbsp__ddrenorm(ph, pl); + --et; + stbsp__ddmulthi(p2h, p2l, ph, stbsp__negtop[et]); + stbsp__ddmultlo(p2h, p2l, ph, pl, stbsp__negtop[et], stbsp__negtoperr[et]); + ph = p2h; + pl = p2l; + } + } else { + if (eb) { + e = eb; + if (eb > 22) + eb = 22; + e -= eb; + stbsp__ddmulthi(ph, pl, d, stbsp__bot[eb]); + if (e) { + stbsp__ddrenorm(ph, pl); + stbsp__ddmulthi(p2h, p2l, ph, stbsp__bot[e]); + stbsp__ddmultlos(p2h, p2l, stbsp__bot[e], pl); + ph = p2h; + pl = p2l; + } + } + if (et) { + stbsp__ddrenorm(ph, pl); + --et; + stbsp__ddmulthi(p2h, p2l, ph, stbsp__top[et]); + stbsp__ddmultlo(p2h, p2l, ph, pl, stbsp__top[et], stbsp__toperr[et]); + ph = p2h; + pl = p2l; + } + } + } + stbsp__ddrenorm(ph, pl); + *ohi = ph; + *olo = pl; +} + +// given a float value, returns the significant bits in bits, and the position of the +// decimal point in decimal_pos. +/-INF and NAN are specified by special values +// returned in the decimal_pos parameter. +// frac_digits is absolute normally, but if you want from first significant digits (got %g and %e), or in 0x80000000 +static stbsp__int32 stbsp__real_to_str(char const **start, stbsp__uint32 *len, char *out, stbsp__int32 *decimal_pos, double value, stbsp__uint32 frac_digits) +{ + double d; + stbsp__int64 bits = 0; + stbsp__int32 expo, e, ng, tens; + + d = value; + STBSP__COPYFP(bits, d); + expo = (stbsp__int32)((bits >> 52) & 2047); + ng = (stbsp__int32)((stbsp__uint64) bits >> 63); + if (ng) + d = -d; + + if (expo == 2047) // is nan or inf? + { + *start = (bits & ((((stbsp__uint64)1) << 52) - 1)) ? "NaN" : "Inf"; + *decimal_pos = STBSP__SPECIAL; + *len = 3; + return ng; + } + + if (expo == 0) // is zero or denormal + { + if (((stbsp__uint64) bits << 1) == 0) // do zero + { + *decimal_pos = 1; + *start = out; + out[0] = '0'; + *len = 1; + return ng; + } + // find the right expo for denormals + { + stbsp__int64 v = ((stbsp__uint64)1) << 51; + while ((bits & v) == 0) { + --expo; + v >>= 1; + } + } + } + + // find the decimal exponent as well as the decimal bits of the value + { + double ph, pl; + + // log10 estimate - very specifically tweaked to hit or undershoot by no more than 1 of log10 of all expos 1..2046 + tens = expo - 1023; + tens = (tens < 0) ? ((tens * 617) / 2048) : (((tens * 1233) / 4096) + 1); + + // move the significant bits into position and stick them into an int + stbsp__raise_to_power10(&ph, &pl, d, 18 - tens); + + // get full as much precision from double-double as possible + stbsp__ddtoS64(bits, ph, pl); + + // check if we undershot + if (((stbsp__uint64)bits) >= stbsp__tento19th) + ++tens; + } + + // now do the rounding in integer land + frac_digits = (frac_digits & 0x80000000) ? ((frac_digits & 0x7ffffff) + 1) : (tens + frac_digits); + if ((frac_digits < 24)) { + stbsp__uint32 dg = 1; + if ((stbsp__uint64)bits >= stbsp__powten[9]) + dg = 10; + while ((stbsp__uint64)bits >= stbsp__powten[dg]) { + ++dg; + if (dg == 20) + goto noround; + } + if (frac_digits < dg) { + stbsp__uint64 r; + // add 0.5 at the right position and round + e = dg - frac_digits; + if ((stbsp__uint32)e >= 24) + goto noround; + r = stbsp__powten[e]; + bits = bits + (r / 2); + if ((stbsp__uint64)bits >= stbsp__powten[dg]) + ++tens; + bits /= r; + } + noround:; + } + + // kill long trailing runs of zeros + if (bits) { + stbsp__uint32 n; + for (;;) { + if (bits <= 0xffffffff) + break; + if (bits % 1000) + goto donez; + bits /= 1000; + } + n = (stbsp__uint32)bits; + while ((n % 1000) == 0) + n /= 1000; + bits = n; + donez:; + } + + // convert to string + out += 64; + e = 0; + for (;;) { + stbsp__uint32 n; + char *o = out - 8; + // do the conversion in chunks of U32s (avoid most 64-bit divides, worth it, constant denomiators be damned) + if (bits >= 100000000) { + n = (stbsp__uint32)(bits % 100000000); + bits /= 100000000; + } else { + n = (stbsp__uint32)bits; + bits = 0; + } + while (n) { + out -= 2; + *(stbsp__uint16 *)out = *(stbsp__uint16 *)&stbsp__digitpair.pair[(n % 100) * 2]; + n /= 100; + e += 2; + } + if (bits == 0) { + if ((e) && (out[0] == '0')) { + ++out; + --e; + } + break; + } + while (out != o) { + *--out = '0'; + ++e; + } + } + + *decimal_pos = tens; + *start = out; + *len = e; + return ng; +} + +#undef stbsp__ddmulthi +#undef stbsp__ddrenorm +#undef stbsp__ddmultlo +#undef stbsp__ddmultlos +#undef STBSP__SPECIAL +#undef STBSP__COPYFP + +#endif // STB_SPRINTF_NOFLOAT + +// clean up +#undef stbsp__uint16 +#undef stbsp__uint32 +#undef stbsp__int32 +#undef stbsp__uint64 +#undef stbsp__int64 +#undef STBSP__UNALIGNED + +#endif // STB_SPRINTF_IMPLEMENTATION + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ +DN_GCC_WARNING_POP +DN_MSVC_WARNING_POP + +DN_API void DN_BeginFrame (); + +#define DN_SPrintF(...) STB_SPRINTF_DECORATE(sprintf)(__VA_ARGS__) +#define DN_SNPrintF(...) STB_SPRINTF_DECORATE(snprintf)(__VA_ARGS__) +#define DN_VSPrintF(...) STB_SPRINTF_DECORATE(vsprintf)(__VA_ARGS__) +#define DN_VSNPrintF(...) STB_SPRINTF_DECORATE(vsnprintf)(__VA_ARGS__) + +DN_API bool DN_MemEq (void const *lhs, DN_USize lhs_size, void const *rhs, DN_USize rhs_size); + +DN_API DN_U64 DN_AtomicSetValue64 (DN_U64 volatile *target, DN_U64 value); +DN_API DN_U32 DN_AtomicSetValue32 (DN_U32 volatile *target, DN_U32 value); + +DN_API DN_CPUIDResult DN_CPUID (DN_CPUIDArgs args); +DN_API DN_USize DN_CPUHasFeatureArray (DN_CPUReport const *report, DN_CPUFeatureQuery *features, DN_USize features_size); +DN_API bool DN_CPUHasFeature (DN_CPUReport const *report, DN_CPUFeature feature); +DN_API bool DN_CPUHasAllFeatures (DN_CPUReport const *report, DN_CPUFeature const *features, DN_USize features_size); +DN_API void DN_CPUSetFeature (DN_CPUReport *report, DN_CPUFeature feature); +DN_API DN_CPUReport DN_CPUGetReport (); + +DN_API void DN_TicketMutex_Begin (DN_TicketMutex *mutex); +DN_API void DN_TicketMutex_End (DN_TicketMutex *mutex); +DN_API DN_UInt DN_TicketMutex_MakeTicket (DN_TicketMutex *mutex); +DN_API void DN_TicketMutex_BeginTicket (DN_TicketMutex const *mutex, DN_UInt ticket); +DN_API bool DN_TicketMutex_CanLock (DN_TicketMutex const *mutex, DN_UInt ticket); + +DN_API void DN_BitUnsetInplace (DN_USize *flags, DN_USize bitfield); +DN_API void DN_BitSetInplace (DN_USize *flags, DN_USize bitfield); +DN_API bool DN_BitIsSet (DN_USize bits, DN_USize bits_to_set); +DN_API bool DN_BitIsNotSet (DN_USize bits, DN_USize bits_to_check); +#define DN_BitClearNextLSB(value) (value) & ((value) - 1) + +DN_API DN_I64 DN_SafeAddI64 (DN_I64 a, DN_I64 b); +DN_API DN_I64 DN_SafeMulI64 (DN_I64 a, DN_I64 b); + +DN_API DN_U64 DN_SafeAddU64 (DN_U64 a, DN_U64 b); +DN_API DN_U64 DN_SafeMulU64 (DN_U64 a, DN_U64 b); + +DN_API DN_U64 DN_SafeSubU64 (DN_U64 a, DN_U64 b); +DN_API DN_U32 DN_SafeSubU32 (DN_U32 a, DN_U32 b); + +DN_API int DN_SaturateCastUSizeToInt (DN_USize val); +DN_API DN_I8 DN_SaturateCastUSizeToI8 (DN_USize val); +DN_API DN_I16 DN_SaturateCastUSizeToI16 (DN_USize val); +DN_API DN_I32 DN_SaturateCastUSizeToI32 (DN_USize val); +DN_API DN_I64 DN_SaturateCastUSizeToI64 (DN_USize val); + +DN_API int DN_SaturateCastU64ToInt (DN_U64 val); +DN_API DN_I8 DN_SaturateCastU8ToI8 (DN_U64 val); +DN_API DN_I16 DN_SaturateCastU16ToI16 (DN_U64 val); +DN_API DN_I32 DN_SaturateCastU32ToI32 (DN_U64 val); +DN_API DN_I64 DN_SaturateCastU64ToI64 (DN_U64 val); +DN_API DN_UInt DN_SaturateCastU64ToUInt (DN_U64 val); +DN_API DN_U8 DN_SaturateCastU64ToU8 (DN_U64 val); +DN_API DN_U16 DN_SaturateCastU64ToU16 (DN_U64 val); +DN_API DN_U32 DN_SaturateCastU64ToU32 (DN_U64 val); + +DN_API DN_U8 DN_SaturateCastUSizeToU8 (DN_USize val); +DN_API DN_U16 DN_SaturateCastUSizeToU16 (DN_USize val); +DN_API DN_U32 DN_SaturateCastUSizeToU32 (DN_USize val); +DN_API DN_U64 DN_SaturateCastUSizeToU64 (DN_USize val); + +DN_API int DN_SaturateCastISizeToInt (DN_ISize val); +DN_API DN_I8 DN_SaturateCastISizeToI8 (DN_ISize val); +DN_API DN_I16 DN_SaturateCastISizeToI16 (DN_ISize val); +DN_API DN_I32 DN_SaturateCastISizeToI32 (DN_ISize val); +DN_API DN_I64 DN_SaturateCastISizeToI64 (DN_ISize val); + +DN_API DN_UInt DN_SaturateCastISizeToUInt (DN_ISize val); +DN_API DN_U8 DN_SaturateCastISizeToU8 (DN_ISize val); +DN_API DN_U16 DN_SaturateCastISizeToU16 (DN_ISize val); +DN_API DN_U32 DN_SaturateCastISizeToU32 (DN_ISize val); +DN_API DN_U64 DN_SaturateCastISizeToU64 (DN_ISize val); + +DN_API DN_ISize DN_SaturateCastI64ToISize (DN_I64 val); +DN_API DN_I8 DN_SaturateCastI64ToI8 (DN_I64 val); +DN_API DN_I16 DN_SaturateCastI64ToI16 (DN_I64 val); +DN_API DN_I32 DN_SaturateCastI64ToI32 (DN_I64 val); + +DN_API DN_UInt DN_SaturateCastI64ToUInt (DN_I64 val); +DN_API DN_ISize DN_SaturateCastI64ToUSize (DN_I64 val); +DN_API DN_U8 DN_SaturateCastI64ToU8 (DN_I64 val); +DN_API DN_U16 DN_SaturateCastI64ToU16 (DN_I64 val); +DN_API DN_U32 DN_SaturateCastI64ToU32 (DN_I64 val); +DN_API DN_U64 DN_SaturateCastI64ToU64 (DN_I64 val); + +DN_API DN_I8 DN_SaturateCastIntToI8 (int val); +DN_API DN_I16 DN_SaturateCastIntToI16 (int val); +DN_API DN_U8 DN_SaturateCastIntToU8 (int val); +DN_API DN_U16 DN_SaturateCastIntToU16 (int val); +DN_API DN_U32 DN_SaturateCastIntToU32 (int val); +DN_API DN_U64 DN_SaturateCastIntToU64 (int val); + +DN_API void DN_ASanPoisonMemoryRegion (void const volatile *ptr, DN_USize size); +DN_API void DN_ASanUnpoisonMemoryRegion (void const volatile *ptr, DN_USize size); + +DN_API DN_F32 DN_EpsilonClampF32 (DN_F32 value, DN_F32 target, DN_F32 epsilon); + +DN_API DN_Arena DN_ArenaFromBuffer (void *buffer, DN_USize size, DN_ArenaFlags flags); +DN_API DN_Arena DN_ArenaFromMemFuncs (DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs); +DN_API void DN_ArenaDeinit (DN_Arena *arena); +DN_API bool DN_ArenaCommit (DN_Arena *arena, DN_U64 size); +DN_API bool DN_ArenaCommitTo (DN_Arena *arena, DN_U64 pos); +DN_API bool DN_ArenaGrow (DN_Arena *arena, DN_U64 reserve, DN_U64 commit); +DN_API void * DN_ArenaAlloc (DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZMem zmem); +DN_API void * DN_ArenaAllocContiguous (DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZMem zmem); +DN_API void * DN_ArenaCopy (DN_Arena *arena, void const *data, DN_U64 size, uint8_t align); +DN_API void DN_ArenaPopTo (DN_Arena *arena, DN_U64 init_used); +DN_API void DN_ArenaPop (DN_Arena *arena, DN_U64 amount); +DN_API DN_U64 DN_ArenaPos (DN_Arena const *arena); +DN_API void DN_ArenaClear (DN_Arena *arena); +DN_API bool DN_ArenaOwnsPtr (DN_Arena const *arena, void *ptr); +DN_API DN_Str8x64 DN_ArenaInfoStr8x64 (DN_ArenaInfo info); +DN_API DN_ArenaStats DN_ArenaSumStatsArray (DN_ArenaStats const *array, DN_USize size); +DN_API DN_ArenaStats DN_ArenaSumStats (DN_ArenaStats lhs, DN_ArenaStats rhs); +DN_API DN_ArenaStats DN_ArenaSumArenaArrayToStats(DN_Arena const *array, DN_USize size); +DN_API DN_ArenaTempMem DN_ArenaTempMemBegin (DN_Arena *arena); +DN_API void DN_ArenaTempMemEnd (DN_ArenaTempMem mem); +#define DN_ArenaNew(arena, T, zmem) (T *)DN_ArenaAlloc(arena, sizeof(T), alignof(T), zmem) +#define DN_ArenaNewZ(arena, T) (T *)DN_ArenaAlloc(arena, sizeof(T), alignof(T), DN_ZMem_Yes) + +#define DN_ArenaNewContiguous(arena, T, zmem) (T *)DN_ArenaAllocContiguous(arena, sizeof(T), alignof(T), zmem) +#define DN_ArenaNewContiguousZ(arena, T) (T *)DN_ArenaAllocContiguous(arena, sizeof(T), alignof(T), DN_ZMem_Yes) + +#define DN_ArenaNewArray(arena, T, count, zmem) (T *)DN_ArenaAlloc(arena, sizeof(T) * (count), alignof(T), zmem) +#define DN_ArenaNewArrayZ(arena, T, count) (T *)DN_ArenaAlloc(arena, sizeof(T) * (count), alignof(T), DN_ZMem_Yes) + +#define DN_ArenaNewCopy(arena, T, src) (T *)DN_ArenaCopy (arena, (src), sizeof(T), alignof(T)) +#define DN_ArenaNewArrayCopy(arena, T, src, count) (T *)DN_ArenaCopy (arena, (src), sizeof(T) * (count), alignof(T)) + +DN_API DN_Pool DN_PoolFromArena (DN_Arena *arena, DN_U8 align); +DN_API bool DN_PoolIsValid (DN_Pool const *pool); +DN_API void * DN_PoolAlloc (DN_Pool *pool, DN_USize size); +DN_API void DN_PoolDealloc (DN_Pool *pool, void *ptr); +DN_API void * DN_PoolCopy (DN_Pool *pool, void const *data, DN_U64 size, uint8_t align); +#define DN_PoolNew(pool, T) (T *)DN_PoolAlloc(pool, sizeof(T)) +#define DN_PoolNewArray(pool, T, count) (T *)DN_PoolAlloc(pool, count * sizeof(T)) +#define DN_PoolNewCopy(pool, T, src) (T *)DN_PoolCopy (pool, (src), sizeof(T), alignof(T)) +#define DN_PoolNewArrayCopy(pool, T, src, count) (T *)DN_PoolCopy (pool, (src), sizeof(T) * (count), alignof(T)) + +DN_API bool DN_CharIsAlphabet (char ch); +DN_API bool DN_CharIsDigit (char ch); +DN_API bool DN_CharIsAlphaNum (char ch); +DN_API bool DN_CharIsWhitespace (char ch); +DN_API bool DN_CharIsHex (char ch); +DN_API char DN_CharToLower (char ch); +DN_API char DN_CharToUpper (char ch); + +DN_API DN_U64FromResult DN_U64FromStr8 (DN_Str8 string, char separator); +DN_API DN_U64FromResult DN_U64FromPtr (void const *data, DN_USize size, char separator); +DN_API DN_U64 DN_U64FromPtrUnsafe (void const *data, DN_USize size, char separator); +DN_API DN_U64FromResult DN_U64FromHexPtr (void const *hex, DN_USize hex_count); +DN_API DN_U64 DN_U64FromHexPtrUnsafe (void const *hex, DN_USize hex_count); +DN_API DN_U64FromResult DN_U64FromHexStr8 (DN_Str8 hex); +DN_API DN_U64 DN_U64FromHexStr8Unsafe (DN_Str8 hex); +DN_API DN_I64FromResult DN_I64FromStr8 (DN_Str8 string, char separator); +DN_API DN_I64FromResult DN_I64FromPtr (void const *data, DN_USize size, char separator); +DN_API DN_I64 DN_I64FromPtrUnsafe (void const *data, DN_USize size, char separator); + +DN_API DN_USize DN_FmtVSize (DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API DN_USize DN_FmtSize (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_FmtAppendResult DN_FmtVAppend (char *buf, DN_USize *buf_size, DN_USize buf_max, char const *fmt, va_list args); +DN_API DN_FmtAppendResult DN_FmtAppend (char *buf, DN_USize *buf_size, DN_USize buf_max, char const *fmt, ...); +DN_API DN_FmtAppendResult DN_FmtAppendTruncate (char *buf, DN_USize *buf_size, DN_USize buf_max, DN_Str8 truncator, char const *fmt, ...); +DN_API DN_USize DN_CStr8Size (char const *src); +DN_API DN_USize DN_CStr16Size (wchar_t const *src); + +#define DN_Str16Lit(string) DN_Str16{(wchar_t *)(string), sizeof(string)/sizeof(string[0]) - 1} +#define DN_Str8Lit(c_str) DN_Literal(DN_Str8){(char *)(c_str), sizeof(c_str) - 1} +#define DN_Str8PrintFmt(string) (int)((string).size), (string).data +#define DN_Str8FromPtr(data, size) DN_Literal(DN_Str8){(char *)(data), (DN_USize)(size)} +#define DN_Str8FromStruct(ptr) DN_Str8FromPtr((ptr)->data, (ptr)->size) +DN_API DN_Str8 DN_Str8FromCStr8 (char const *src); +DN_API DN_Str8 DN_Str8FromArena (DN_Arena *arena, DN_USize size, DN_ZMem z_mem); +DN_API DN_Str8 DN_Str8FromPool (DN_Pool *pool, DN_USize size); +DN_API DN_Str8 DN_Str8FromPtrArena (DN_Arena *arena, void const *data, DN_USize size); +DN_API DN_Str8 DN_Str8FromPtrPool (DN_Pool *pool, void const *data, DN_USize size); +DN_API DN_Str8 DN_Str8FromStr8Arena (DN_Arena *arena, DN_Str8 string); +DN_API DN_Str8 DN_Str8FromStr8Pool (DN_Pool *pool, DN_Str8 string); +DN_API DN_Str8 DN_Str8FromFmtArena (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8 DN_Str8FromFmtVArena (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API DN_Str8 DN_Str8FromFmtPool (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8 DN_Str8FromByteCountType (DN_ByteCountType type); +DN_API DN_Str8x32 DN_Str8x32FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x32 DN_Str8x32FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API DN_Str8x64 DN_Str8x64FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x64 DN_Str8x64FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API DN_Str8x128 DN_Str8x128FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x256 DN_Str8x256FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API DN_Str8x256 DN_Str8x256FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x256 DN_Str8x256FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API DN_Str8x32 DN_Str8x32FromU64 (DN_U64 val, char separator); +DN_API bool DN_Str8IsAll (DN_Str8 string, DN_Str8IsAllType is_all); +DN_API char * DN_Str8End (DN_Str8 string); +DN_API DN_Str8 DN_Str8Slice (DN_Str8 string, DN_USize offset, DN_USize size); +DN_API DN_Str8 DN_Str8Advance (DN_Str8 string, DN_USize amount); +DN_API DN_Str8 DN_Str8NextLine (DN_Str8 string); +DN_API DN_Str8BSplitResult DN_Str8BSplitArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size); +DN_API DN_Str8BSplitResult DN_Str8BSplit (DN_Str8 string, DN_Str8 find); +DN_API DN_Str8BSplitResult DN_Str8BSplitLastArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size); +DN_API DN_Str8BSplitResult DN_Str8BSplitLast (DN_Str8 string, DN_Str8 find); +DN_API DN_USize DN_Str8Split (DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_USize splits_count, DN_Str8SplitIncludeEmptyStrings mode); +DN_API DN_Str8SplitResult DN_Str8SplitArena (DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode); +DN_API DN_Str8FindResult DN_Str8FindStr8Array (DN_Str8 string, DN_Str8 const *find, DN_USize find_size, DN_Str8EqCase eq_case); +DN_API DN_Str8FindResult DN_Str8FindStr8 (DN_Str8 string, DN_Str8 find, DN_Str8EqCase eq_case); +DN_API DN_Str8FindResult DN_Str8Find (DN_Str8 string, uint32_t flags); +DN_API DN_Str8 DN_Str8Segment (DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char); +DN_API DN_Str8 DN_Str8ReverseSegment (DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char); +DN_API bool DN_Str8Eq (DN_Str8 lhs, DN_Str8 rhs, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive); +DN_API bool DN_Str8EqInsensitive (DN_Str8 lhs, DN_Str8 rhs); +DN_API bool DN_Str8StartsWith (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive); +DN_API bool DN_Str8StartsWithInsensitive(DN_Str8 string, DN_Str8 prefix); +DN_API bool DN_Str8EndsWith (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive); +DN_API bool DN_Str8EndsWithInsensitive (DN_Str8 string, DN_Str8 prefix); +DN_API bool DN_Str8HasChar (DN_Str8 string, char ch); +DN_API DN_Str8 DN_Str8TrimPrefix (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive); +DN_API DN_Str8 DN_Str8TrimHexPrefix (DN_Str8 string); +DN_API DN_Str8 DN_Str8TrimSuffix (DN_Str8 string, DN_Str8 suffix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive); +DN_API DN_Str8 DN_Str8TrimAround (DN_Str8 string, DN_Str8 trim_string); +DN_API DN_Str8 DN_Str8TrimHeadWhitespace (DN_Str8 string); +DN_API DN_Str8 DN_Str8TrimTailWhitespace (DN_Str8 string); +DN_API DN_Str8 DN_Str8TrimWhitespaceAround (DN_Str8 string); +DN_API DN_Str8 DN_Str8TrimByteOrderMark (DN_Str8 string); +DN_API DN_Str8 DN_Str8FileNameFromPath (DN_Str8 path); +DN_API DN_Str8 DN_Str8FileNameNoExtension (DN_Str8 path); +DN_API DN_Str8 DN_Str8FilePathNoExtension (DN_Str8 path); +DN_API DN_Str8 DN_Str8FileExtension (DN_Str8 path); +DN_API DN_Str8 DN_Str8FileDirectoryFromPath(DN_Str8 path); +DN_API DN_Str8 DN_Str8AppendF (DN_Arena *arena, DN_Str8 string, char const *fmt, ...); +DN_API DN_Str8 DN_Str8AppendFV (DN_Arena *arena, DN_Str8 string, char const *fmt, va_list args); +DN_API DN_Str8 DN_Str8FillF (DN_Arena *arena, DN_USize count, char const *fmt, ...); +DN_API DN_Str8 DN_Str8FillFV (DN_Arena *arena, DN_USize count, char const *fmt, va_list args); +DN_API void DN_Str8Remove (DN_Str8 *string, DN_USize offset, DN_USize size); +DN_API DN_Str8TruncateResult DN_Str8TruncateMiddle (DN_Arena *arena, DN_Str8 str8, DN_U32 side_size, DN_Str8 truncator); +DN_API DN_Str8 DN_Str8Lower (DN_Arena *arena, DN_Str8 string); +DN_API DN_Str8 DN_Str8Upper (DN_Arena *arena, DN_Str8 string); + +DN_API DN_Str8Builder DN_Str8BuilderFromArena (DN_Arena *arena); +DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrRef (DN_Arena *arena, DN_Str8 const *strings, DN_USize size); +DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrCopy (DN_Arena *arena, DN_Str8 const *strings, DN_USize size); +DN_API DN_Str8Builder DN_Str8BuilderFromBuilder (DN_Arena *arena, DN_Str8Builder const *builder); +DN_API bool DN_Str8BuilderAddArrayRef (DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize size, DN_Str8BuilderAdd add); +DN_API bool DN_Str8BuilderAddArrayCopy (DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize size, DN_Str8BuilderAdd add); +DN_API bool DN_Str8BuilderAddFV (DN_Str8Builder *builder, DN_Str8BuilderAdd add, DN_FMT_ATTRIB char const *fmt, va_list args); +#define DN_Str8BuilderAppendArrayRef(builder, strings, size) DN_Str8BuilderAddArrayRef(builder, strings, size, DN_Str8BuilderAdd_Append) +#define DN_Str8BuilderAppendArrayCopy(builder, strings, size) DN_Str8BuilderAddArrayCopy(builder, strings, size, DN_Str8BuilderAdd_Append) +#define DN_Str8BuilderAppendSliceRef(builder, slice) DN_Str8BuilderAddArrayRef(builder, slice.data, slice.size, DN_Str8BuilderAdd_Append) +#define DN_Str8BuilderAppendSliceCopy(builder, slice) DN_Str8BuilderAddArrayCopy(builder, slice.data, slice.size, DN_Str8BuilderAdd_Append) +DN_API bool DN_Str8BuilderAppendRef (DN_Str8Builder *builder, DN_Str8 string); +DN_API bool DN_Str8BuilderAppendCopy (DN_Str8Builder *builder, DN_Str8 string); +#define DN_Str8BuilderAppendFV(builder, fmt, args) DN_Str8BuilderAddFV(builder, DN_Str8BuilderAdd_Append, fmt, args) +DN_API bool DN_Str8BuilderAppendF (DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...); +DN_API bool DN_Str8BuilderAppendBytesRef (DN_Str8Builder *builder, void const *ptr, DN_USize size); +DN_API bool DN_Str8BuilderAppendBytesCopy (DN_Str8Builder *builder, void const *ptr, DN_USize size); +DN_API bool DN_Str8BuilderAppendBuilderRef (DN_Str8Builder *dest, DN_Str8Builder const *src); +DN_API bool DN_Str8BuilderAppendBuilderCopy (DN_Str8Builder *dest, DN_Str8Builder const *src); +#define DN_Str8BuilderPrependArrayRef(builder, strings, size) DN_Str8BuilderAddArrayRef(builder, strings, size, DN_Str8BuilderAdd_Prepend) +#define DN_Str8BuilderPrependArrayCopy(builder, strings, size) DN_Str8BuilderAddArrayCopy(builder, strings, size, DN_Str8BuilderAdd_Prepend) +#define DN_Str8BuilderPrependSliceRef(builder, slice) DN_Str8BuilderAddArrayRef(builder, slice.data, slice.size, DN_Str8BuilderAdd_Prepend) +#define DN_Str8BuilderPrependSliceCopy(builder, slice) DN_Str8BuilderAddArrayCopy(builder, slice.data, slice.size, DN_Str8BuilderAdd_Prepend) +DN_API bool DN_Str8BuilderPrependRef (DN_Str8Builder *builder, DN_Str8 string); +DN_API bool DN_Str8BuilderPrependCopy (DN_Str8Builder *builder, DN_Str8 string); +#define DN_Str8BuilderPrependFV(builder, fmt, args) DN_Str8BuilderAddFV(builder, DN_Str8BuilderAdd_Prepend, fmt, args) +DN_API bool DN_Str8BuilderPrependF (DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...); +DN_API bool DN_Str8BuilderErase (DN_Str8Builder *builder, DN_Str8 string); +DN_API DN_Str8 DN_Str8BuilderBuild (DN_Str8Builder const *builder, DN_Arena *arena); +DN_API DN_Str8 DN_Str8BuilderBuildDelimited (DN_Str8Builder const *builder, DN_Str8 delimiter, DN_Arena *arena); +DN_API DN_Slice DN_Str8BuilderBuildSlice (DN_Str8Builder const *builder, DN_Arena *arena); + +DN_API int DN_EncodeUTF8Codepoint (uint8_t utf8[4], uint32_t codepoint); +DN_API int DN_EncodeUTF16Codepoint (uint16_t utf16[2], uint32_t codepoint); + +DN_API DN_U8 DN_U8FromHexNibble (char hex); +DN_API DN_NibbleFromU8Result DN_NibbleFromU8 (DN_U8 u8); + +DN_API DN_USize DN_BytesFromHexPtr (void const *hex, DN_USize hex_count, void *dest, DN_USize dest_count); +DN_API DN_Str8 DN_BytesFromHexPtrArena (void const *hex, DN_USize hex_count, DN_Arena *arena); +DN_API DN_USize DN_BytesFromHexStr8 (DN_Str8 hex, void *dest, DN_USize dest_count); +DN_API DN_Str8 DN_BytesFromHexStr8Arena (DN_Str8 hex, DN_Arena *arena); +DN_API DN_U8x16 DN_BytesFromHex32Ptr (void const *hex, DN_USize hex_count); +DN_API DN_U8x32 DN_BytesFromHex64Ptr (void const *hex, DN_USize hex_count); + +DN_API DN_HexU64Str8 DN_HexFromU64 (DN_U64 value, DN_HexFromU64Type type); +DN_API DN_USize DN_HexFromBytesPtr (void const *bytes, DN_USize bytes_count, void *hex, DN_USize hex_count); +DN_API DN_Str8 DN_HexFromBytesPtrArena (void const *bytes, DN_USize bytes_count, DN_Arena *arena); +DN_API DN_Hex32 DN_HexFromBytes16Ptr (void const *bytes, DN_USize bytes_count); +DN_API DN_Hex64 DN_HexFromBytes32Ptr (void const *bytes, DN_USize bytes_count); +DN_API DN_Hex128 DN_HexFromBytes64Ptr (void const *bytes, DN_USize bytes_count); + +DN_API DN_Str8x128 DN_AgeStr8FromMsU64 (DN_U64 duration_ms, DN_AgeUnit units); +DN_API DN_Str8x128 DN_AgeStr8FromSecU64 (DN_U64 duration_ms, DN_AgeUnit units); +DN_API DN_Str8x128 DN_AgeStr8FromSecF64 (DN_F64 sec, DN_AgeUnit units); + +DN_API DN_ByteCountResult DN_ByteCountFromType (DN_U64 bytes, DN_ByteCountType type); +#define DN_ByteCount(bytes) DN_ByteCountFromType(bytes, DN_ByteCountType_Auto) +DN_API DN_Str8x32 DN_ByteCountStr8x32FromType (DN_U64 bytes, DN_ByteCountType type); +#define DN_ByteCountStr8x32(bytes) DN_ByteCountStr8x32FromType(bytes, DN_ByteCountType_Auto) + +#define DN_ProfilerZoneLoop(prof, name, index) \ + DN_ProfilerZone DN_UniqueName(zone_) = DN_ProfilerBeginZone(prof, DN_Str8Lit(name), index), DN_UniqueName(dummy_) = {}; \ + DN_UniqueName(dummy_).begin_tsc == 0; \ + DN_ProfilerEndZone(prof, DN_UniqueName(zone_)), DN_UniqueName(dummy_).begin_tsc = 1 + +#define DN_ProfilerZoneLoopAuto(prof, name) DN_ProfilerZoneLoop(prof, name, __COUNTER__ + 1) +DN_API DN_Profiler DN_ProfilerInit (DN_ProfilerAnchor *anchors, DN_USize count, DN_USize anchors_per_frame, DN_ProfilerTSCNowFunc *tsc_now, DN_U64 tsc_frequency); +DN_API DN_ProfilerZone DN_ProfilerBeginZone (DN_Profiler *profiler, DN_Str8 name, DN_U16 anchor_index); +#define DN_ProfilerBeginZoneAuto(prof, name) DN_ProfilerBeginZone(prof, DN_Str8Lit(name), __COUNTER__ + 1) +DN_API void DN_ProfilerEndZone (DN_Profiler *profiler, DN_ProfilerZone zone); +DN_API DN_USize DN_ProfilerFrameCount (DN_Profiler const *profiler); +DN_API DN_ProfilerAnchorArray DN_ProfilerFrameAnchorsFromIndex (DN_Profiler *profiler, DN_USize frame_index); +DN_API DN_ProfilerAnchorArray DN_ProfilerFrameAnchors (DN_Profiler *profiler); +DN_API void DN_ProfilerNewFrame (DN_Profiler *profiler); +DN_API void DN_ProfilerDump (DN_Profiler *profiler); +DN_API DN_F64 DN_ProfilerSecFromTSC (DN_Profiler *profiler, DN_U64 duration_tsc); +DN_API DN_F64 DN_ProfilerMsFromTSC (DN_Profiler *profiler, DN_U64 duration_tsc); + +#endif // !defined(DN_BASE_H) +// DN: Single header generator commented out this header => #include "Base/dn_base_os.h" +#if !defined(DN_BASE_OS_H) +#define DN_BASE_OS_H + +// DN: Single header generator commented out this header => #include "../dn_base_inc.h" + +// NOTE: OS primitives that the OS layer can provide for the base layer but is optional. + +struct DN_StackTraceFrame +{ + DN_U64 address; + DN_U64 line_number; + DN_Str8 file_name; + DN_Str8 function_name; +}; + +struct DN_StackTraceRawFrame +{ + void *process; + DN_U64 base_addr; +}; + +struct DN_StackTraceWalkResult +{ + void *process; // [Internal] Windows handle to the process + DN_U64 *base_addr; // The addresses of the functions in the stack trace + DN_U16 size; // The number of `base_addr`'s stored from the walk +}; + +struct DN_StackTraceWalkResultIterator +{ + DN_StackTraceRawFrame raw_frame; + DN_U16 index; +}; + + +#if defined(DN_FREESTANDING) +#define DN_StackTraceWalkStr8FromHeap(...) DN_Str8Lit("N/A") +#define DN_StackTraceWalk(...) +#define DN_StackTraceWalkResultIterate(...) +#define DN_StackTraceWalkResultToStr8(...) DN_Str8Lit("N/A") +#define DN_StackTraceWalkStr8(...) DN_Str8Lit("N/A") +#define DN_StackTraceWalkStr8FromHeap(...) DN_Str8Lit("N/A") +#define DN_StackTraceGetFrames(...) +#define DN_StackTraceRawFrameToFrame(...) +#define DN_StackTracePrint(...) +#define DN_StackTraceReloadSymbols(...) +#else +DN_API DN_StackTraceWalkResult DN_StackTraceWalk (struct DN_Arena *arena, DN_U16 limit); +DN_API bool DN_StackTraceWalkResultIterate(DN_StackTraceWalkResultIterator *it, DN_StackTraceWalkResult const *walk); +DN_API DN_Str8 DN_StackTraceWalkResultToStr8 (struct DN_Arena *arena, DN_StackTraceWalkResult const *walk, DN_U16 skip); +DN_API DN_Str8 DN_StackTraceWalkStr8 (struct DN_Arena *arena, DN_U16 limit, DN_U16 skip); +DN_API DN_Str8 DN_StackTraceWalkStr8FromHeap (DN_U16 limit, DN_U16 skip); +DN_API DN_Slice DN_StackTraceGetFrames (struct DN_Arena *arena, DN_U16 limit); +DN_API DN_StackTraceFrame DN_StackTraceRawFrameToFrame (struct DN_Arena *arena, DN_StackTraceRawFrame raw_frame); +DN_API void DN_StackTracePrint (DN_U16 limit); +DN_API void DN_StackTraceReloadSymbols (); +#endif +#endif // !defined(DN_BASE_OS_H) +// DN: Single header generator commented out this header => #include "Base/dn_base_assert.h" +#if !defined(DN_BASE_ASSERT_H) +#define DN_BASE_ASSERT_H + +#define DN_HardAssertF(expr, fmt, ...) \ + do { \ + if (!(expr)) { \ + DN_Str8 stack_trace_ = DN_StackTraceWalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \ + DN_LOG_ErrorF("Hard assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ + DN_Str8PrintFmt(stack_trace_), \ + ##__VA_ARGS__); \ + DN_DebugBreak; \ + } \ + } while (0) +#define DN_HardAssert(expr) DN_HardAssertF(expr, "") + +// NOTE: Our default assert requires stack traces which has a bit of a chicken-and-egg problem if +// we're trying to detect some code related to the DN startup sequence. If we try to assert before +// the OS layer is initialised stack-traces will try to use temporary memory which requires TLS to +// be setup which belongs to the OS. +// +// This causes recursion errors as they call into each other. We use RawAsserts for these kind of +// checks. +#if defined(DN_NO_ASSERT) + #define DN_RawAssert(...) + #define DN_Assert(...) + #define DN_AssertOnce(...) + #define DN_AssertF(...) + #define DN_AssertFOnce(...) +#else + #define DN_RawAssert(expr) do { if (!(expr)) DN_DebugBreak; } while (0) + + #define DN_AssertF(expr, fmt, ...) \ + do { \ + if (!(expr)) { \ + DN_Str8 stack_trace_ = DN_StackTraceWalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \ + DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ + DN_Str8PrintFmt(stack_trace_), \ + ##__VA_ARGS__); \ + DN_DebugBreak; \ + } \ + } while (0) + + #define DN_AssertFOnce(expr, fmt, ...) \ + do { \ + static bool once = true; \ + if (!(expr) && once) { \ + once = false; \ + DN_Str8 stack_trace_ = DN_StackTraceWalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \ + DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ + DN_Str8PrintFmt(stack_trace_), \ + ##__VA_ARGS__); \ + DN_DebugBreak; \ + } \ + } while (0) + + #define DN_Assert(expr) DN_AssertF((expr), "") + #define DN_AssertOnce(expr) DN_AssertFOnce((expr), "") +#endif + +#define DN_InvalidCodePathF(fmt, ...) DN_HardAssertF(0, fmt, ##__VA_ARGS__) +#define DN_InvalidCodePath DN_InvalidCodePathF("Invalid code path triggered") +#define DN_StaticAssert(expr) \ + DN_GCC_WARNING_PUSH \ + DN_GCC_WARNING_DISABLE(-Wunused-local-typedefs) \ + typedef char DN_TokenCombine(static_assert_dummy__, __LINE__)[(expr) ? 1 : -1]; \ + DN_GCC_WARNING_POP + +#define DN_Check(expr) DN_CheckF(expr, "") +#if defined(DN_NO_CHECK_BREAK) + #define DN_CheckF(expr, fmt, ...) \ + ((expr) ? true : (DN_LOG_WarningF(fmt, ##__VA_ARGS__), false)) +#else + #define DN_CheckF(expr, fmt, ...) \ + ((expr) ? true : (DN_LOG_ErrorF(fmt, ##__VA_ARGS__), DN_StackTracePrint(128 /*limit*/), DN_DebugBreak, false)) +#endif + +#endif +// DN: Single header generator commented out this header => #include "Base/dn_base_log.h" +#if !defined(DN_BASE_LOG_H) +#define DN_BASE_LOG_H + +// DN: Single header generator commented out this header => #include "../dn_base_inc.h" + +enum DN_LOGType +{ + DN_LOGType_Debug, + DN_LOGType_Info, + DN_LOGType_Warning, + DN_LOGType_Error, + DN_LOGType_Count, +}; + +enum DN_LOGBold +{ + DN_LOGBold_No, + DN_LOGBold_Yes, +}; + +struct DN_LOGStyle +{ + DN_LOGBold bold; + bool colour; + DN_U8 r, g, b; +}; + +struct DN_LOGTypeParam +{ + bool is_u32_enum; + DN_U32 u32; + DN_Str8 str8; +}; + +enum DN_LOGColourType +{ + DN_LOGColourType_Fg, + DN_LOGColourType_Bg, +}; + +struct DN_LOGDate +{ + DN_U16 year; + DN_U8 month; + DN_U8 day; + + DN_U8 hour; + DN_U8 minute; + DN_U8 second; +}; + +struct DN_LOGPrefixSize +{ + DN_USize size; + DN_USize padding; +}; + +typedef void DN_LOGEmitFromTypeFVFunc(DN_LOGTypeParam type, void *user_data, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, va_list args); + +#define DN_LOG_ResetEscapeCode "\x1b[0m" +#define DN_LOG_BoldEscapeCode "\x1b[1m" +DN_API DN_Str8 DN_LOG_ColourEscapeCodeStr8FromRGB(DN_LOGColourType colour, DN_U8 r, DN_U8 g, DN_U8 b); +DN_API DN_Str8 DN_LOG_ColourEscapeCodeStr8FromU32(DN_LOGColourType colour, DN_U32 value); +DN_API DN_LOGPrefixSize DN_LOG_MakePrefix (DN_LOGStyle style, DN_LOGTypeParam type, DN_CallSite call_site, DN_LOGDate date, char *dest, DN_USize dest_size); +DN_API void DN_LOG_SetEmitFromTypeFVFunc (DN_LOGEmitFromTypeFVFunc *print_func, void *user_data); +DN_API void DN_LOG_EmitFromType (DN_LOGTypeParam type, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_LOGTypeParam DN_LOG_MakeU32LogTypeParam (DN_LOGType type); +#define DN_LOG_DebugF(fmt, ...) DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Debug), DN_CALL_SITE, fmt, ##__VA_ARGS__) +#define DN_LOG_InfoF(fmt, ...) DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Info), DN_CALL_SITE, fmt, ##__VA_ARGS__) +#define DN_LOG_WarningF(fmt, ...) DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Warning), DN_CALL_SITE, fmt, ##__VA_ARGS__) +#define DN_LOG_ErrorF(fmt, ...) DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Error), DN_CALL_SITE, fmt, ##__VA_ARGS__) +#endif // !defined(DN_BASE_LOG_H) +// DN: Single header generator commented out this header => #include "Base/dn_base_containers.h" +#if !defined(DN_CONTAINERS_H) +#define DN_CONTAINERS_H + +// DN: Single header generator commented out this header => #include "../dn_base_inc.h" + +struct DN_Ring +{ + DN_U64 size; + char *base; + DN_U64 write_pos; + DN_U64 read_pos; +}; + +// NOTE: DN_CArray ///////////////////////////////////////////////////////////////////////////////// +enum DN_ArrayErase +{ + DN_ArrayErase_Unstable, + DN_ArrayErase_Stable, +}; + +enum DN_ArrayAdd +{ + DN_ArrayAdd_Append, + DN_ArrayAdd_Prepend, +}; + +struct DN_ArrayEraseResult +{ + // The next index your for-index should be set to such that you can continue + // to iterate the remainder of the array, e.g: + // + // for (DN_USize index = 0; index < array.size; index++) { + // if (erase) + // index = DN_FArray_EraseRange(&array, index, -3, DN_ArrayErase_Unstable); + // } + DN_USize it_index; + DN_USize items_erased; // The number of items erased +}; + +template struct DN_ArrayFindResult +{ + T *data; // Pointer to the value if a match is found, null pointer otherwise + DN_USize index; // Index to the value if a match is found, 0 otherwise +}; + +#if !defined(DN_NO_SARRAY) +// NOTE: DN_SArray ///////////////////////////////////////////////////////////////////////////////// +template struct DN_SArray +{ + T *data; // Pointer to the start of the array items in the block of memory + DN_USize size; // Number of items currently in the array + DN_USize max; // Maximum number of items this array can store + + T *begin() { return data; } + T *end () { return data + size; } + T const *begin() const { return data; } + T const *end () const { return data + size; } +}; +#endif // !defined(DN_NO_SARRAY) + +#if !defined(DN_NO_FARRAY) +// NOTE: DN_FArray ///////////////////////////////////////////////////////////////////////////////// +template struct DN_FArray +{ + T data[N]; // Pointer to the start of the array items in the block of memory + DN_USize size; // Number of items currently in the array + + T *begin() { return data; } + T *end () { return data + size; } + T const *begin() const { return data; } + T const *end () const { return data + size; } +}; + +template using DN_FArray8 = DN_FArray; +template using DN_FArray16 = DN_FArray; +template using DN_FArray32 = DN_FArray; +template using DN_FArray64 = DN_FArray; +#endif // !defined(DN_NO_FARRAY) + +#if !defined(DN_NO_DSMAP) +// NOTE: DN_DSMap ////////////////////////////////////////////////////////////////////////////////// +enum DN_DSMapKeyType +{ + // Key | Key Hash | Map Index + DN_DSMapKeyType_Invalid, + DN_DSMapKeyType_U64, // U64 | Hash(U64) | Hash(U64) % map_size + DN_DSMapKeyType_U64NoHash, // U64 | U64 | U64 % map_size + DN_DSMapKeyType_Buffer, // Buffer | Hash(buffer) | Hash(buffer) % map_size + DN_DSMapKeyType_BufferAsU64NoHash, // Buffer | U64(buffer[0:4]) | U64(buffer[0:4]) % map_size +}; + +struct DN_DSMapKey +{ + DN_DSMapKeyType type; + DN_U32 hash; // Hash to lookup in the map. If it equals, we check that the original key payload matches + void const *buffer_data; + DN_U32 buffer_size; + DN_U64 u64; + bool no_copy_buffer; +}; + +template +struct DN_DSMapSlot +{ + DN_DSMapKey key; // Hash table lookup key + T value; // Hash table value +}; + +typedef DN_U32 DN_DSMapFlags; +enum DN_DSMapFlags_ +{ + DN_DSMapFlags_Nil = 0, + DN_DSMapFlags_DontFreeArenaOnResize = 1 << 0, +}; + +using DN_DSMapHashFunction = DN_U32(DN_DSMapKey key, DN_U32 seed); +template struct DN_DSMap +{ + DN_U32 *hash_to_slot; // Mapping from hash to a index in the slots array + DN_DSMapSlot *slots; // Values of the array stored contiguously, non-sorted order + DN_U32 size; // Total capacity of the map and is a power of two + DN_U32 occupied; // Number of slots used in the hash table + DN_Arena *arena; // Backing arena for the hash table + DN_Pool pool; // Allocator for keys that are variable-sized buffers + DN_U32 initial_size; // Initial map size, map cannot shrink on erase below this size + DN_DSMapHashFunction *hash_function; // Custom hashing function to use if field is set + DN_U32 hash_seed; // Seed for the hashing function, when 0, DN_DS_MAP_DEFAULT_HASH_SEED is used + DN_DSMapFlags flags; +}; + +template struct DN_DSMapResult +{ + bool found; + DN_DSMapSlot *slot; + T *value; +}; +#endif // !defined(DN_NO_DSMAP) + +#if !defined(DN_NO_LIST) +// NOTE: DN_List /////////////////////////////////////////////////////////////////////////////////// +template struct DN_ListChunk +{ + T *data; + DN_USize size; + DN_USize count; + DN_ListChunk *next; + DN_ListChunk *prev; +}; + +template struct DN_ListIterator +{ + DN_B32 init; // True if DN_List_Iterate has been called at-least once on this iterator + DN_ListChunk *chunk; // The chunk that the iterator is reading from + DN_USize chunk_data_index; // The index in the chunk the iterator is referencing + DN_USize index; // The index of the item in the list as if it was flat array + T *data; // Pointer to the data the iterator is referencing. Nullptr if invalid. +}; + +template struct DN_List +{ + DN_USize count; // Cumulative count of all items made across all list chunks + DN_USize chunk_size; // When new ListChunk's are required, the minimum 'data' entries to allocate for that node. + DN_ListChunk *head; + DN_ListChunk *tail; +}; +#endif // !defined(DN_NO_LIST) + +// NOTE: Macros for operating on data structures that are embedded into a C style struct or from a +// set of defined variables from the available scope. Keep it stupid simple, structs and functions. +// Minimal amount of container types with flexible construction leads to less duplicated container +// code and less template meta-programming. +// +// LArray => Literal Array +// Define a C array and size: +// +// ``` +// MyStruct buffer[TB_ASType_Count] = {}; +// DN_USize size = 0; +// MyStruct *item = DN_LArray_Make(buffer, size, DN_ArrayCountU(buffer), DN_ZMem_No); +// ``` +// +// IArray => Intrusive Array +// Define a struct with the members 'data', 'size' and 'max': +// +// ``` +// struct MyArray { +// MyStruct *data; +// DN_USize size; +// DN_USize max; +// } my_array = {}; +// +// MyStruct *item = DN_IArray_Make(&my_array, MyArray, DN_ZMem_No); +// ``` +// ISLList => Intrusive Singly Linked List +// Define a struct with the members 'next': +// +// ``` +// struct MyLinkItem { +// int data; +// MyLinkItem *next; +// } my_link = {}; +// +// MyLinkItem *first_item = DN_ISLList_Detach(&my_link, MyLinkItem); +// ``` + +#define DN_DLList_Init(list) \ + (list)->next = (list)->prev = (list) + +#define DN_DLList_IsSentinel(list, item) ((list) == (item)) + +#define DN_DLList_InitArena(list, T, arena) \ + do { \ + (list) = DN_ArenaNew(arena, T, DN_ZMem_Yes); \ + DN_DLList_Init(list); \ + } while (0) + +#define DN_DLList_InitPool(list, T, pool) \ + do { \ + (list) = DN_PoolNew(pool, T); \ + DN_DLList_Init(list); \ + } while (0) + +#define DN_DLList_Detach(item) \ + do { \ + if (item) { \ + (item)->prev->next = (item)->next; \ + (item)->next->prev = (item)->prev; \ + (item)->next = nullptr; \ + (item)->prev = nullptr; \ + } \ + } while (0) + +#define DN_DLList_Dequeue(list, dest_ptr) \ + if (DN_DLList_HasItems(list)) { \ + dest_ptr = (list)->next; \ + DN_DLList_Detach(dest_ptr); \ + } + +#define DN_DLList_Append(list, item) \ + do { \ + if (item) { \ + if ((item)->next) \ + DN_DLList_Detach(item); \ + (item)->next = (list)->next; \ + (item)->prev = (list); \ + (item)->next->prev = (item); \ + (item)->prev->next = (item); \ + } \ + } while (0) + +#define DN_DLList_Prepend(list, item) \ + do { \ + if (item) { \ + if ((item)->next) \ + DN_DLList_Detach(item); \ + (item)->next = (list); \ + (item)->prev = (list)->prev; \ + (item)->next->prev = (item); \ + (item)->prev->next = (item); \ + } \ + } while (0) + +#define DN_DLList_IsEmpty(list) \ + (!(list) || ((list) == (list)->next)) + +#define DN_DLList_IsInit(list) \ + ((list)->next && (list)->prev) + +#define DN_DLList_HasItems(list) \ + ((list) && ((list) != (list)->next)) + +#define DN_DLList_ForEach(it, list) \ + auto *it = (list)->next; (it) != (list); (it) = (it)->next + +#define DN_DoublyLLDetach(head, ptr) \ + do { \ + if ((head) && (head) == (ptr)) \ + (head) = (head)->next; \ + if ((ptr)) { \ + if ((ptr)->next) \ + (ptr)->next->prev = (ptr)->prev; \ + if ((ptr)->prev) \ + (ptr)->prev->next = (ptr)->next; \ + (ptr)->prev = (ptr)->next = 0; \ + } \ + } while (0) + +#define DN_DoublyLLAppend(head, ptr) \ + do { \ + if ((ptr)) { \ + DN_AssertF((ptr)->prev == 0 && (ptr)->next == 0, "Detach the pointer first"); \ + (ptr)->prev = (head); \ + (ptr)->next = 0; \ + if ((head)) { \ + (ptr)->next = (head)->next; \ + (head)->next = (ptr); \ + } else { \ + (head) = (ptr); \ + } \ + } \ + } while (0) + +#define DN_DoublyLLPrepend(head, ptr) \ + do { \ + if ((ptr)) { \ + DN_AssertF((ptr)->prev == 0 && (ptr)->next == 0, "Detach the pointer first"); \ + (ptr)->prev = nullptr; \ + (ptr)->next = (head); \ + if ((head)) { \ + (ptr)->prev = (head)->prev; \ + (head)->prev = (ptr); \ + } else { \ + (head) = (ptr); \ + } \ + } \ + } while (0) + +#define DN_ISLList_Detach(list) (decltype(list))DN_CSLList_Detach((void **)&(list), (void **)&(list)->next) + +#define DN_LArray_ResizeFromPool(c_array, size, max, pool, new_max) DN_CArray2_ResizeFromPool((void **)&(c_array), size, max, sizeof((c_array)[0]), pool, new_max) +#define DN_LArray_GrowFromPool(c_array, size, max, pool, new_max) DN_CArray2_GrowFromPool((void **)&(c_array), size, max, sizeof((c_array)[0]), pool, new_max) +#define DN_LArray_GrowIfNeededFromPool(c_array, size, max, pool, add_count) DN_CArray2_GrowIfNeededFromPool((void **)(c_array), size, max, sizeof((c_array)[0]), pool, add_count) +#define DN_LArray_MakeArray(c_array, size, max, count, z_mem) (decltype(&(c_array)[0]))DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), count, z_mem) +#define DN_LArray_MakeArrayZ(c_array, size, max, count) (decltype(&(c_array)[0]))DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), count, DN_ZMem_Yes) +#define DN_LArray_Make(c_array, size, max, z_mem) (decltype(&(c_array)[0]))DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), 1, z_mem) +#define DN_LArray_MakeZ(c_array, size, max) (decltype(&(c_array)[0]))DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), 1, DN_ZMem_Yes) +#define DN_LArray_AddArray(c_array, size, max, items, count, add) (decltype(&(c_array)[0]))DN_CArray2_AddArray(c_array, size, max, sizeof((c_array)[0]), items, count, add) +#define DN_LArray_Add(c_array, size, max, item, add) (decltype(&(c_array)[0]))DN_CArray2_AddArray(c_array, size, max, sizeof((c_array)[0]), &item, 1, add) +#define DN_LArray_AppendArray(c_array, size, max, items, count) (decltype(&(c_array)[0]))DN_CArray2_AddArray(c_array, size, max, sizeof((c_array)[0]), items, count, DN_ArrayAdd_Append) +#define DN_LArray_Append(c_array, size, max, item) (decltype(&(c_array)[0]))DN_CArray2_AddArray(c_array, size, max, sizeof((c_array)[0]), &item, 1, DN_ArrayAdd_Append) +#define DN_LArray_PrependArray(c_array, size, max, items, count) (decltype(&(c_array)[0]))DN_CArray2_AddArray(c_array, size, max, sizeof((c_array)[0]), items, count, DN_ArrayAdd_Prepend) +#define DN_LArray_Prepend(c_array, size, max, item) (decltype(&(c_array)[0]))DN_CArray2_AddArray(c_array, size, max, sizeof((c_array)[0]), &item, 1, DN_ArrayAdd_Prepend) +#define DN_LArray_EraseRange(c_array, size, begin_index, count, erase) DN_CArray2_EraseRange(c_array, size, sizeof((c_array)[0]), begin_index, count, erase) +#define DN_LArray_Erase(c_array, size, index, erase) DN_CArray2_EraseRange(c_array, size, sizeof((c_array)[0]), index, 1, erase) +#define DN_LArray_InsertArray(c_array, size, max, index, items, count) (decltype(&(c_array)[0]))DN_CArray2_InsertArray(c_array, size, max, sizeof((c_array)[0]), index, items, count) +#define DN_LArray_Insert(c_array, size, max, index, item) (decltype(&(c_array)[0]))DN_CArray2_InsertArray(c_array, size, max, sizeof((c_array)[0]), index, &item, 1) + +#define DN_IArray_ResizeFromPool(array, pool, new_max) DN_CArray2_ResizeFromPool((void **)(&(array)->data), &(array)->size, &(array)->max, sizeof((array)->data[0]), pool, new_max) +#define DN_IArray_GrowFromPool(array, pool, new_max) DN_CArray2_GrowFromPool((void **)(&(array)->data), &(array)->size, &(array)->max, sizeof((array)->data[0]), pool, new_max) +#define DN_IArray_GrowIfNeededFromPool(array, pool, add_count) DN_CArray2_GrowIfNeededFromPool((void **)(&(array)->data), (array)->size, &(array)->max, sizeof((array)->data[0]), pool, add_count) +#define DN_IArray_MakeArray(array, count, z_mem) (decltype(&((array)->data)[0]))DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), count, z_mem) +#define DN_IArray_MakeArrayZ(array, count) (decltype(&((array)->data)[0]))DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), count, DN_ZMem_Yes) +#define DN_IArray_Make(array, z_mem) (decltype(&((array)->data)[0]))DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), 1, z_mem) +#define DN_IArray_MakeZ(array) (decltype(&((array)->data)[0]))DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), 1, DN_ZMem_Yes) +#define DN_IArray_AddArray(array, items, count, add) (decltype(&((array)->data)[0]))DN_CArray2_AddArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), items, count, add) +#define DN_IArray_Add(array, item, add) (decltype(&((array)->data)[0]))DN_CArray2_AddArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), &item, 1, add) +#define DN_IArray_AppendArray(array, items, count) (decltype(&((array)->data)[0]))DN_CArray2_AddArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), items, count, DN_ArrayAdd_Append) +#define DN_IArray_Append(array, item) (decltype(&((array)->data)[0]))DN_CArray2_AddArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), &item, 1, DN_ArrayAdd_Append) +#define DN_IArray_PrependArray(array, items, count) (decltype(&((array)->data)[0]))DN_CArray2_AddArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), items, count, DN_ArrayAdd_Prepend) +#define DN_IArray_Prepend(array, item) (decltype(&((array)->data)[0]))DN_CArray2_AddArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), &item, 1, DN_ArrayAdd_Prepend) +#define DN_IArray_EraseRange(array, begin_index, count, erase) DN_CArray2_EraseRange((array)->data, &(array)->size, sizeof(((array)->data)[0]), begin_index, count, erase) +#define DN_IArray_Erase(array, index, erase) DN_CArray2_EraseRange((array)->data, &(array)->size, sizeof(((array)->data)[0]), index, 1, erase) +#define DN_IArray_InsertArray(array, index, items, count) (decltype(&((array)->data)[0]))DN_CArray2_InsertArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), index, items, count) +#define DN_IArray_Insert(array, index, item, count) (decltype(&((array)->data)[0]))DN_CArray2_InsertArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), index, &item, 1) + +DN_API DN_ArrayEraseResult DN_CArray2_EraseRange (void *data, DN_USize *size, DN_USize elem_size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase); +DN_API void *DN_CArray2_MakeArray (void *data, DN_USize *size, DN_USize max, DN_USize data_size, DN_USize make_size, DN_ZMem z_mem); +DN_API void *DN_CArray2_AddArray (void *data, DN_USize *size, DN_USize max, DN_USize data_size, void const *elems, DN_USize elems_count, DN_ArrayAdd add); +DN_API bool DN_CArray2_Resize (void **data, DN_USize *size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize new_max); +DN_API bool DN_CArray2_Grow (void **data, DN_USize *size, DN_USize *max, DN_USize data_size, DN_Pool *pool, DN_USize new_max); +DN_API bool DN_CArray2_GrowIfNeededFromPool (void **data, DN_USize size, DN_USize *max, DN_USize data_size, DN_Pool *pool); +DN_API void *DN_CSLList_Detach (void **link, void **next); + +DN_API bool DN_Ring_HasSpace (DN_Ring const *ring, DN_U64 size); +DN_API bool DN_Ring_HasData (DN_Ring const *ring, DN_U64 size); +DN_API void DN_Ring_Write (DN_Ring *ring, void const *src, DN_U64 src_size); +#define DN_Ring_WriteStruct(ring, item) DN_Ring_Write((ring), (item), sizeof(*(item))) +DN_API void DN_Ring_Read (DN_Ring *ring, void *dest, DN_U64 dest_size); +#define DN_Ring_ReadStruct(ring, dest) DN_Ring_Read((ring), (dest), sizeof(*(dest))) + +template DN_ArrayEraseResult DN_CArray_EraseRange (T *data, DN_USize *size, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase); +template T * DN_CArray_MakeArray (T *data, DN_USize *size, DN_USize max, DN_USize count, DN_ZMem z_mem); +template T * DN_CArray_InsertArray (T *data, DN_USize *size, DN_USize max, DN_USize index, T const *items, DN_USize count); +template T DN_CArray_PopFront (T *data, DN_USize *size, DN_USize count); +template T DN_CArray_PopBack (T *data, DN_USize *size, DN_USize count); +template DN_ArrayFindResult DN_CArray_Find (T *data, DN_USize size, T const &value); + +// NOTE: DN_SArray ///////////////////////////////////////////////////////////////////////////////// +#if !defined(DN_NO_SARRAY) +template DN_SArray DN_SArray_Init (DN_Arena *arena, DN_USize size, DN_ZMem z_mem); +template DN_SArray DN_SArray_InitSlice (DN_Arena *arena, DN_Slice slice, DN_USize size, DN_ZMem z_mem); +template DN_SArray DN_SArray_InitCArray (DN_Arena *arena, T const (&array)[N], DN_USize size, DN_ZMem); +template DN_SArray DN_SArray_InitBuffer (T* buffer, DN_USize size); +template bool DN_SArray_IsValid (DN_SArray const *array); +template DN_Slice DN_SArray_Slice (DN_SArray const *array); +template T * DN_SArray_AddArray (DN_SArray *array, T const *items, DN_USize count); +template T * DN_SArray_AddCArray (DN_SArray *array, T const (&items)[N]); +template T * DN_SArray_Add (DN_SArray *array, T const &item); +#define DN_SArray_AddArrayAssert(...) DN_HardAssert(DN_SArray_AddArray(__VA_ARGS__)) +#define DN_SArray_AddCArrayAssert(...) DN_HardAssert(DN_SArray_AddCArray(__VA_ARGS__)) +#define DN_SArray_AddAssert(...) DN_HardAssert(DN_SArray_Add(__VA_ARGS__)) +template T * DN_SArray_MakeArray (DN_SArray *array, DN_USize count, DN_ZMem z_mem); +template T * DN_SArray_Make (DN_SArray *array, DN_ZMem z_mem); +#define DN_SArray_MakeArrayAssert(...) DN_HardAssert(DN_SArray_MakeArray(__VA_ARGS__)) +#define DN_SArray_MakeAssert(...) DN_HardAssert(DN_SArray_Make(__VA_ARGS__)) +template T * DN_SArray_InsertArray (DN_SArray *array, DN_USize index, T const *items, DN_USize count); +template T * DN_SArray_InsertCArray (DN_SArray *array, DN_USize index, T const (&items)[N]); +template T * DN_SArray_Insert (DN_SArray *array, DN_USize index, T const &item); +#define DN_SArray_InsertArrayAssert(...) DN_HardAssert(DN_SArray_InsertArray(__VA_ARGS__)) +#define DN_SArray_InsertCArrayAssert(...) DN_HardAssert(DN_SArray_InsertCArray(__VA_ARGS__)) +#define DN_SArray_InsertAssert(...) DN_HardAssert(DN_SArray_Insert(__VA_ARGS__)) +template T DN_SArray_PopFront (DN_SArray *array, DN_USize count); +template T DN_SArray_PopBack (DN_SArray *array, DN_USize count); +template DN_ArrayEraseResult DN_SArray_EraseRange (DN_SArray *array, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase); +template void DN_SArray_Clear (DN_SArray *array); +#endif // !defined(DN_NO_SARRAY) + +#if !defined(DN_NO_FARRAY) +#define DN_FArray_ToSArray(array) DN_SArray_InitBuffer((array)->data, DN_ArrayCountU((array)->data)) +template DN_FArray DN_FArray_Init (T const *array, DN_USize count); +#define DN_FArray_HasData(array) ((array).data && (array).size) +template DN_FArray DN_FArray_InitSlice (DN_Slice slice); +template DN_FArray DN_FArray_InitCArray (T const (&items)[K]); +template bool DN_FArray_IsValid (DN_FArray const *array); +template DN_USize DN_FArray_Max (DN_FArray const *) { return N; } +template DN_Slice DN_FArray_Slice (DN_FArray const *array); +template T * DN_FArray_AddArray (DN_FArray *array, T const *items, DN_USize count); +template T * DN_FArray_AddCArray (DN_FArray *array, T const (&items)[K]); +template T * DN_FArray_Add (DN_FArray *array, T const &item); +#define DN_FArray_AddArrayAssert(...) DN_HardAssert(DN_FArray_AddArray(__VA_ARGS__)) +#define DN_FArray_AddCArrayAssert(...) DN_HardAssert(DN_FArray_AddCArray(__VA_ARGS__)) +#define DN_FArray_AddAssert(...) DN_HardAssert(DN_FArray_Add(__VA_ARGS__)) +template T * DN_FArray_MakeArray (DN_FArray *array, DN_USize count, DN_ZMem z_mem); +template T * DN_FArray_Make (DN_FArray *array, DN_ZMem z_mem); +#define DN_FArray_MakeArrayAssert(...) DN_HardAssert(DN_FArray_MakeArray(__VA_ARGS__)) +#define DN_FArray_MakeAssert(...) DN_HardAssert(DN_FArray_Make(__VA_ARGS__)) +template T * DN_FArray_InsertArray (DN_FArray *array, T const &item, DN_USize index); +template T * DN_FArray_InsertCArray (DN_FArray *array, DN_USize index, T const (&items)[K]); +template T * DN_FArray_Insert (DN_FArray *array, DN_USize index, T const &item); +#define DN_FArray_InsertArrayAssert(...) DN_HardAssert(DN_FArray_InsertArray(__VA_ARGS__)) +#define DN_FArray_InsertAssert(...) DN_HardAssert(DN_FArray_Insert(__VA_ARGS__)) +template T DN_FArray_PopFront (DN_FArray *array, DN_USize count); +template T DN_FArray_PopBack (DN_FArray *array, DN_USize count); +template DN_ArrayFindResult DN_FArray_Find (DN_FArray *array, T const &find); +template DN_ArrayEraseResult DN_FArray_EraseRange (DN_FArray *array, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase); +template void DN_FArray_Clear (DN_FArray *array); +#endif // !defined(DN_NO_FARRAY) + +#if !defined(DN_NO_SLICE) +#define DN_TO_SLICE(val) DN_Slice_Init((val)->data, (val)->size) +#define DN_Slice_InitCArray(array) DN_Slice_Init(array, DN_ArrayCountU(array)) +template DN_Slice DN_Slice_Init (T* const data, DN_USize size); +template DN_Slice DN_Slice_InitCArrayCopy (DN_Arena *arena, T const (&array)[N]); +template DN_Slice DN_Slice_Copy (DN_Arena *arena, DN_Slice slice); +template DN_Slice DN_Slice_CopyPtr (DN_Arena *arena, T* const data, DN_USize size); +template DN_Slice DN_Slice_Alloc (DN_Arena *arena, DN_USize size, DN_ZMem z_mem); + DN_Str8 DN_Slice_Str8Render (DN_Arena *arena, DN_Slice array, DN_Str8 separator); + DN_Str8 DN_Slice_Str8RenderSpaceSeparated (DN_Arena *arena, DN_Slice array); + DN_Str16 DN_Slice_Str16Render (DN_Arena *arena, DN_Slice array, DN_Str16 separator); + DN_Str16 DN_Slice_Str16RenderSpaceSeparated(DN_Arena *arena, DN_Slice array); +#endif // !defined(DN_NO_SLICE) + +#if !defined(DN_NO_DSMAP) +template DN_DSMap DN_DSMap_Init (DN_Arena *arena, DN_U32 size, DN_DSMapFlags flags); +template void DN_DSMap_Deinit (DN_DSMap *map, DN_ZMem z_mem); +template bool DN_DSMap_IsValid (DN_DSMap const *map); +template DN_U32 DN_DSMap_Hash (DN_DSMap const *map, DN_DSMapKey key); +template DN_U32 DN_DSMap_HashToSlotIndex (DN_DSMap const *map, DN_DSMapKey key); +template DN_DSMapResult DN_DSMap_Find (DN_DSMap const *map, DN_DSMapKey key); +template DN_DSMapResult DN_DSMap_Make (DN_DSMap *map, DN_DSMapKey key); +template DN_DSMapResult DN_DSMap_Set (DN_DSMap *map, DN_DSMapKey key, T const &value); +template DN_DSMapResult DN_DSMap_FindKeyU64 (DN_DSMap const *map, DN_U64 key); +template DN_DSMapResult DN_DSMap_MakeKeyU64 (DN_DSMap *map, DN_U64 key); +template DN_DSMapResult DN_DSMap_SetKeyU64 (DN_DSMap *map, DN_U64 key, T const &value); +template DN_DSMapResult DN_DSMap_FindKeyStr8 (DN_DSMap const *map, DN_Str8 key); +template DN_DSMapResult DN_DSMap_MakeKeyStr8 (DN_DSMap *map, DN_Str8 key); +template DN_DSMapResult DN_DSMap_SetKeyStr8 (DN_DSMap *map, DN_Str8 key, T const &value); +template bool DN_DSMap_Resize (DN_DSMap *map, DN_U32 size); +template bool DN_DSMap_Erase (DN_DSMap *map, DN_DSMapKey key); +template bool DN_DSMap_EraseKeyU64 (DN_DSMap *map, DN_U64 key); +template bool DN_DSMap_EraseKeyStr8 (DN_DSMap *map, DN_Str8 key); +template DN_DSMapKey DN_DSMap_KeyBuffer (DN_DSMap const *map, void const *data, DN_U32 size); +template DN_DSMapKey DN_DSMap_KeyBufferAsU64NoHash (DN_DSMap const *map, void const *data, DN_U32 size); +template DN_DSMapKey DN_DSMap_KeyU64 (DN_DSMap const *map, DN_U64 u64); +template DN_DSMapKey DN_DSMap_KeyStr8 (DN_DSMap const *map, DN_Str8 string); +#define DN_DSMap_KeyCStr8(map, string) DN_DSMap_KeyBuffer(map, string, sizeof((string))/sizeof((string)[0]) - 1) +DN_API DN_DSMapKey DN_DSMap_KeyU64NoHash (DN_U64 u64); +DN_API bool DN_DSMap_KeyEquals (DN_DSMapKey lhs, DN_DSMapKey rhs); +DN_API bool operator== (DN_DSMapKey lhs, DN_DSMapKey rhs); +#endif // !defined(DN_NO_DSMAP) + +#if !defined(DN_NO_LIST) +template DN_List DN_List_Init (DN_USize chunk_size); +template DN_List DN_List_InitCArray (DN_Arena *arena, DN_USize chunk_size, T const (&array)[N]); +template T * DN_List_At (DN_List *list, DN_USize index, DN_ListChunk **at_chunk); +template void DN_List_Clear (DN_List *list); +template bool DN_List_Iterate (DN_List *list, DN_ListIterator *it, DN_USize start_index); +template T * DN_List_MakeArena (DN_List *list, DN_Arena *arena, DN_USize count); +template T * DN_List_MakePool (DN_List *list, DN_Pool *pool, DN_USize count); +template T * DN_List_AddArena (DN_List *list, DN_Arena *arena, T const &value); +template T * DN_List_AddPool (DN_List *list, DN_Pool *pool, T const &value); +template void DN_List_AddListArena (DN_List *list, DN_Arena *arena, DN_List other); +template void DN_List_AddListArena (DN_List *list, DN_Pool *pool, DN_List other); +template DN_Slice DN_List_ToSliceCopy (DN_List const *list, DN_Arena* arena); +#endif // !defined(DN_NO_LIST) +#endif // !defined(DN_CONTAINER_H) +// DN: Single header generator commented out this header => #include "Base/dn_base_leak.h" +// DN: Single header generator commented out this header => #include "../dn_base_inc.h" + +enum DN_LeakAllocFlag +{ + DN_LeakAllocFlag_Freed = 1 << 0, + DN_LeakAllocFlag_LeakPermitted = 1 << 1, +}; + +struct DN_LeakAlloc +{ + void *ptr; // 8 Pointer to the allocation being tracked + DN_USize size; // 16 Size of the allocation + DN_USize freed_size; // 24 Store the size of the allocation when it is freed + DN_Str8 stack_trace; // 40 Stack trace at the point of allocation + DN_Str8 freed_stack_trace; // 56 Stack trace of where the allocation was freed + DN_U16 flags; // 72 Bit flags from `DN_LeakAllocFlag` +}; + +// NOTE: We aim to keep the allocation record as light as possible as memory tracking can get +// expensive. Enforce that there is no unexpected padding. +DN_StaticAssert(sizeof(DN_LeakAlloc) == 64 || sizeof(DN_LeakAlloc) == 32); // NOTE: 64 bit vs 32 bit pointers respectively + +struct DN_LeakTracker +{ + DN_DSMap alloc_table; + DN_TicketMutex alloc_table_mutex; + DN_Arena alloc_table_arena; + DN_U64 alloc_table_bytes_allocated_for_stack_traces; +}; + +DN_API void DN_LeakTrackAlloc_ (DN_LeakTracker *leak, void *ptr, DN_USize size, bool alloc_can_leak); +DN_API void DN_LeakTrackDealloc_(DN_LeakTracker *leak, void *ptr); +DN_API void DN_LeakDump_ (DN_LeakTracker *leak); + +#if defined(DN_LEAK_TRACKING) +#define DN_LeakTrackAlloc(leak, ptr, size, alloc_can_leak) DN_LeakTrackAlloc_(leak, ptr, size, alloc_can_leak) +#define DN_LeakTrackDealloc(leak, ptr) DN_LeakTrackDealloc_(leak, ptr) +#define DN_LeakDump(leak) DN_LeakDump_(leak) +#else +#define DN_LeakTrackAlloc(leak, ptr, size, alloc_can_leak) do { (void)ptr; (void)size; (void)alloc_can_leak; } while (0) +#define DN_LeakTrackDealloc(leak, ptr) do { (void)ptr; } while (0) +#define DN_LeakDump(leak) do { } while (0) +#endif + + +#endif // !defined(DN_BASE_INC_H) + // DN: Single header generator inlined this file => #include "dn_os_inc.h" +#if !defined(DN_OS_INC_H) +#define DN_OS_INC_H + +#if defined(DN_PLATFORM_WIN32) + // DN: Single header generator commented out this header => #include "OS/dn_os_windows.h" +#if !defined(DN_OS_WINDOWS_H) +#define DN_OS_WINDOWS_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +#if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) + #pragma comment(lib, "bcrypt") + #pragma comment(lib, "winhttp") + #pragma comment(lib, "dbghelp") + #pragma comment(lib, "comdlg32") + #pragma comment(lib, "pathcch") + #pragma comment(lib, "Shell32") // ShellExecuteW + #pragma comment(lib, "shlwapi") +#endif + +#if defined(DN_NO_WINDOWS_H_REPLACEMENT_HEADER) || defined(_INC_WINDOWS) + #define WIN32_LEAN_AND_MEAN + #include // LONG + #include // DN_OS_SecureRNGBytes -> BCryptOpenAlgorithmProvider ... etc + #include // DN_Win_MakeProcessDPIAware -> SetProcessDpiAwareProc + #include // PathRelativePathTO + #include // PathCchCanonicalizeEx + #include // WinHttp* + #include // PROCESS_MEMORY_COUNTERS_EX2 + #include // OPENFILENAMEW + #include +#else + DN_MSVC_WARNING_PUSH + DN_MSVC_WARNING_DISABLE(4201) // warning C4201: nonstandard extension used: nameless struct/union + + // NOTE: basetsd.h ///////////////////////////////////////////////////////////////////////////// + typedef unsigned __int64 ULONG_PTR, *PULONG_PTR; + typedef unsigned __int64 UINT_PTR, *PUINT_PTR; + typedef ULONG_PTR SIZE_T, *PSIZE_T; + typedef __int64 LONG_PTR, *PLONG_PTR; + typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; + typedef unsigned __int64 ULONG64, *PULONG64; + typedef unsigned __int64 DWORD64, *PDWORD64; + + // NOTE: shared/minwindef.h //////////////////////////////////////////////////////////////////// + struct HINSTANCE__ { + int unused; + }; + typedef struct HINSTANCE__ *HINSTANCE; + + typedef unsigned long DWORD; + typedef int BOOL; + typedef int INT; + typedef unsigned long ULONG; + typedef unsigned int UINT; + typedef unsigned short WORD; + typedef unsigned char BYTE; + typedef unsigned char UCHAR; + typedef HINSTANCE HMODULE; /* HMODULEs can be used in place of HINSTANCEs */ + typedef void * HANDLE; + typedef HANDLE HLOCAL; + + typedef unsigned __int64 WPARAM; + typedef LONG_PTR LPARAM; + typedef LONG_PTR LRESULT; + + #define MAX_PATH 260 + + typedef struct _FILETIME { + DWORD dwLowDateTime; + DWORD dwHighDateTime; + } FILETIME, *PFILETIME, *LPFILETIME; + + // NOTE: shared/winerror.h ///////////////////////////////////////////////////////////////////// + // NOTE: GetModuleFileNameW + #define ERROR_INSUFFICIENT_BUFFER 122L // dderror + + // NOTE: um/winnls.h /////////////////////////////////////////////////////////////////////////// + // NOTE: MultiByteToWideChar + #define CP_UTF8 65001 // UTF-8 translation + + // NOTE: um/winnt.h //////////////////////////////////////////////////////////////////////////// + typedef void VOID; + typedef __int64 LONGLONG; + typedef unsigned __int64 ULONGLONG; + typedef void * HANDLE; + typedef char CHAR; + typedef short SHORT; + typedef long LONG; + typedef wchar_t WCHAR; // wc, 16-bit UNICODE character + typedef CHAR * NPSTR, *LPSTR, *PSTR; + typedef WCHAR * NWPSTR, *LPWSTR, *PWSTR; + typedef long HRESULT; + + // NOTE: VirtualAlloc: Allocation Type + #define MEM_RESERVE 0x00002000 + #define MEM_COMMIT 0x00001000 + #define MEM_DECOMMIT 0x00004000 + #define MEM_RELEASE 0x00008000 + + // NOTE: VirtualAlloc: Page Permissions + #define PAGE_NOACCESS 0x01 + #define PAGE_READONLY 0x02 + #define PAGE_READWRITE 0x04 + #define PAGE_GUARD 0x100 + + // NOTE: HeapAlloc + #define HEAP_ZERO_MEMORY 0x00000008 + #define HEAP_NO_SERIALIZE 0x00000001 + #define HEAP_GROWABLE 0x00000002 + #define HEAP_GENERATE_EXCEPTIONS 0x00000004 + #define HEAP_ZERO_MEMORY 0x00000008 + #define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010 + #define HEAP_TAIL_CHECKING_ENABLED 0x00000020 + #define HEAP_FREE_CHECKING_ENABLED 0x00000040 + #define HEAP_DISABLE_COALESCE_ON_FREE 0x00000080 + #define HEAP_CREATE_ALIGN_16 0x00010000 + #define HEAP_CREATE_ENABLE_TRACING 0x00020000 + #define HEAP_CREATE_ENABLE_EXECUTE 0x00040000 + #define HEAP_MAXIMUM_TAG 0x0FFF + #define HEAP_PSEUDO_TAG_FLAG 0x8000 + #define HEAP_TAG_SHIFT 18 + #define HEAP_CREATE_SEGMENT_HEAP 0x00000100 + #define HEAP_CREATE_HARDENED 0x00000200 + + // NOTE: FormatMessageA + #define MAKELANGID(p, s) ((((WORD )(s)) << 10) | (WORD )(p)) + #define LANG_NEUTRAL 0x00 + #define SUBLANG_DEFAULT 0x01 // user default + + // NOTE: CreateFile + #define GENERIC_READ (0x80000000L) + #define GENERIC_WRITE (0x40000000L) + #define GENERIC_EXECUTE (0x20000000L) + #define GENERIC_ALL (0x10000000L) + + #define FILE_APPEND_DATA (0x0004) // file + + // NOTE: CreateFile/FindFirstFile + #define FILE_SHARE_READ 0x00000001 + #define FILE_SHARE_WRITE 0x00000002 + #define FILE_SHARE_DELETE 0x00000004 + + #define FILE_ATTRIBUTE_READONLY 0x00000001 + #define FILE_ATTRIBUTE_HIDDEN 0x00000002 + #define FILE_ATTRIBUTE_SYSTEM 0x00000004 + #define FILE_ATTRIBUTE_DIRECTORY 0x00000010 + #define FILE_ATTRIBUTE_NORMAL 0x00000080 + + // NOTE: STACKFRAME64 + #define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8) + + // NOTE: WaitForSingleObject + #define WAIT_TIMEOUT 258L // dderror + #define STATUS_WAIT_0 ((DWORD )0x00000000L) + #define STATUS_ABANDONED_WAIT_0 ((DWORD )0x00000080L) + + #define S_OK ((HRESULT)0L) + #define S_FALSE ((HRESULT)1L) + + typedef union _ULARGE_INTEGER { + struct { + DWORD LowPart; + DWORD HighPart; + } DUMMYSTRUCTNAME; + struct { + DWORD LowPart; + DWORD HighPart; + } u; + ULONGLONG QuadPart; + } ULARGE_INTEGER; + + typedef union _LARGE_INTEGER { + struct { + DWORD LowPart; + LONG HighPart; + } DUMMYSTRUCTNAME; + struct { + DWORD LowPart; + LONG HighPart; + } u; + LONGLONG QuadPart; + } LARGE_INTEGER; + + typedef struct __declspec(align(16)) _M128A { + ULONGLONG Low; + LONGLONG High; + } M128A, *PM128A; + + typedef struct __declspec(align(16)) _XSAVE_FORMAT { + WORD ControlWord; + WORD StatusWord; + BYTE TagWord; + BYTE Reserved1; + WORD ErrorOpcode; + DWORD ErrorOffset; + WORD ErrorSelector; + WORD Reserved2; + DWORD DataOffset; + WORD DataSelector; + WORD Reserved3; + DWORD MxCsr; + DWORD MxCsr_Mask; + M128A FloatRegisters[8]; + #if defined(_WIN64) + M128A XmmRegisters[16]; + BYTE Reserved4[96]; + #else + M128A XmmRegisters[8]; + BYTE Reserved4[224]; + #endif + } XSAVE_FORMAT, *PXSAVE_FORMAT; + typedef XSAVE_FORMAT XMM_SAVE_AREA32, *PXMM_SAVE_AREA32; + + typedef struct __declspec(align(16)) _CONTEXT { + DWORD64 P1Home; + DWORD64 P2Home; + DWORD64 P3Home; + DWORD64 P4Home; + DWORD64 P5Home; + DWORD64 P6Home; + DWORD ContextFlags; + DWORD MxCsr; + WORD SegCs; + WORD SegDs; + WORD SegEs; + WORD SegFs; + WORD SegGs; + WORD SegSs; + DWORD EFlags; + DWORD64 Dr0; + DWORD64 Dr1; + DWORD64 Dr2; + DWORD64 Dr3; + DWORD64 Dr6; + DWORD64 Dr7; + DWORD64 Rax; + DWORD64 Rcx; + DWORD64 Rdx; + DWORD64 Rbx; + DWORD64 Rsp; + DWORD64 Rbp; + DWORD64 Rsi; + DWORD64 Rdi; + DWORD64 R8; + DWORD64 R9; + DWORD64 R10; + DWORD64 R11; + DWORD64 R12; + DWORD64 R13; + DWORD64 R14; + DWORD64 R15; + DWORD64 Rip; + + union { + XMM_SAVE_AREA32 FltSave; + + struct { + M128A Header[2]; + M128A Legacy[8]; + M128A Xmm0; + M128A Xmm1; + M128A Xmm2; + M128A Xmm3; + M128A Xmm4; + M128A Xmm5; + M128A Xmm6; + M128A Xmm7; + M128A Xmm8; + M128A Xmm9; + M128A Xmm10; + M128A Xmm11; + M128A Xmm12; + M128A Xmm13; + M128A Xmm14; + M128A Xmm15; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + + M128A VectorRegister[26]; + DWORD64 VectorControl; + DWORD64 DebugControl; + DWORD64 LastBranchToRip; + DWORD64 LastBranchFromRip; + DWORD64 LastExceptionToRip; + DWORD64 LastExceptionFromRip; + } CONTEXT; + + typedef struct _LIST_ENTRY { + struct _LIST_ENTRY *Flink; + struct _LIST_ENTRY *Blink; + } LIST_ENTRY, *PLIST_ENTRY, PRLIST_ENTRY; + + typedef struct _RTL_CRITICAL_SECTION_DEBUG { + WORD Type; + WORD CreatorBackTraceIndex; + struct _RTL_CRITICAL_SECTION *CriticalSection; + LIST_ENTRY ProcessLocksList; + DWORD EntryCount; + DWORD ContentionCount; + DWORD Flags; + WORD CreatorBackTraceIndexHigh; + WORD Identifier; + } RTL_CRITICAL_SECTION_DEBUG, *PRTL_CRITICAL_SECTION_DEBUG, RTL_RESOURCE_DEBUG, *PRTL_RESOURCE_DEBUG; + + typedef struct _RTL_CONDITION_VARIABLE { + VOID *Ptr; + } RTL_CONDITION_VARIABLE, *PRTL_CONDITION_VARIABLE; + + #pragma pack(push, 8) + typedef struct _RTL_CRITICAL_SECTION { + PRTL_CRITICAL_SECTION_DEBUG DebugInfo; + + // + // The following three fields control entering and exiting the critical + // section for the resource + // + + LONG LockCount; + LONG RecursionCount; + HANDLE OwningThread; // from the thread's ClientId->UniqueThread + HANDLE LockSemaphore; + ULONG_PTR SpinCount; // force size on 64-bit systems when packed + } RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION; + #pragma pack(pop) + + typedef struct _MODLOAD_DATA { + DWORD ssize; // size of this struct + DWORD ssig; // signature identifying the passed data + VOID *data; // pointer to passed data + DWORD size; // size of passed data + DWORD flags; // options + } MODLOAD_DATA, *PMODLOAD_DATA; + + #define SLMFLAG_VIRTUAL 0x1 + #define SLMFLAG_ALT_INDEX 0x2 + #define SLMFLAG_NO_SYMBOLS 0x4 + + extern "C" + { + __declspec(dllimport) VOID __stdcall RtlCaptureContext(CONTEXT *ContextRecord); + __declspec(dllimport) HANDLE __stdcall GetCurrentProcess(void); + __declspec(dllimport) HANDLE __stdcall GetCurrentThread(void); + __declspec(dllimport) DWORD __stdcall SymSetOptions(DWORD SymOptions); + __declspec(dllimport) BOOL __stdcall SymInitialize(HANDLE hProcess, const CHAR* UserSearchPath, BOOL fInvadeProcess); + __declspec(dllimport) DWORD64 __stdcall SymLoadModuleEx(HANDLE hProcess, HANDLE hFile, CHAR const *ImageName, CHAR const *ModuleName, DWORD64 BaseOfDll, DWORD DllSize, MODLOAD_DATA *Data, DWORD Flags); + __declspec(dllimport) BOOL __stdcall SymUnloadModule64(HANDLE hProcess, DWORD64 BaseOfDll); + } + + // NOTE: um/heapapi.h //////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) HANDLE __stdcall HeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize); + __declspec(dllimport) BOOL __stdcall HeapDestroy(HANDLE hHeap); + __declspec(dllimport) VOID * __stdcall HeapAlloc(HANDLE hHeap, DWORD dwFlags,SIZE_T dwBytes); + __declspec(dllimport) VOID * __stdcall HeapReAlloc(HANDLE hHeap, DWORD dwFlags, VOID *lpMem, SIZE_T dwBytes); + __declspec(dllimport) BOOL __stdcall HeapFree(HANDLE hHeap, DWORD dwFlags, VOID *lpMem); + __declspec(dllimport) SIZE_T __stdcall HeapSize(HANDLE hHeap, DWORD dwFlags, VOID const *lpMem); + __declspec(dllimport) HANDLE __stdcall GetProcessHeap(VOID); + __declspec(dllimport) SIZE_T __stdcall HeapCompact(HANDLE hHeap, DWORD dwFlags); + } + + // NOTE: shared/windef.h //////////////////////////////////////////////////////////////////// + typedef struct tagPOINT + { + LONG x; + LONG y; + } POINT, *PPOINT, *NPPOINT, *LPPOINT; + + // NOTE: handleapi.h /////////////////////////////////////////////////////////////////////////// + #define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1) + + extern "C" + { + __declspec(dllimport) BOOL __stdcall CloseHandle(HANDLE hObject); + } + + // NOTE: consoleapi.h /////////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall WriteConsoleA(HANDLE hConsoleOutput, const VOID* lpBuffer, DWORD nNumberOfCharsToWrite, DWORD *lpNumberOfCharsWritten, VOID *lpReserved); + __declspec(dllimport) BOOL __stdcall AllocConsole(VOID); + __declspec(dllimport) BOOL __stdcall FreeConsole(VOID); + __declspec(dllimport) BOOL __stdcall AttachConsole(DWORD dwProcessId); + __declspec(dllimport) BOOL __stdcall GetConsoleMode(HANDLE hConsoleHandle, DWORD *lpMode); + } + + // NOTE: um/minwinbase.h /////////////////////////////////////////////////////////////////////// + // NOTE: FindFirstFile + #define FIND_FIRST_EX_CASE_SENSITIVE 0x00000001 + #define FIND_FIRST_EX_LARGE_FETCH 0x00000002 + + // NOTE: WaitFor.. + #define WAIT_FAILED ((DWORD)0xFFFFFFFF) + #define WAIT_OBJECT_0 ((STATUS_WAIT_0 ) + 0 ) + #define WAIT_ABANDONED ((STATUS_ABANDONED_WAIT_0 ) + 0 ) + #define WAIT_ABANDONED_0 ((STATUS_ABANDONED_WAIT_0 ) + 0 ) + + // NOTE: CreateProcessW + #define CREATE_UNICODE_ENVIRONMENT 0x00000400 + #define CREATE_NO_WINDOW 0x08000000 + + typedef enum _GET_FILEEX_INFO_LEVELS { + GetFileExInfoStandard, + GetFileExMaxInfoLevel + } GET_FILEEX_INFO_LEVELS; + + typedef struct _SECURITY_ATTRIBUTES { + DWORD nLength; + VOID *lpSecurityDescriptor; + BOOL bInheritHandle; + } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; + + typedef enum _FINDEX_INFO_LEVELS { + FindExInfoStandard, + FindExInfoBasic, + FindExInfoMaxInfoLevel + } FINDEX_INFO_LEVELS; + + typedef enum _FINDEX_SEARCH_OPS { + FindExSearchNameMatch, + FindExSearchLimitToDirectories, + FindExSearchLimitToDevices, + FindExSearchMaxSearchOp + } FINDEX_SEARCH_OPS; + + typedef struct _WIN32_FIND_DATAW { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwReserved0; + DWORD dwReserved1; + WCHAR cFileName[ MAX_PATH ]; + WCHAR cAlternateFileName[ 14 ]; + #ifdef _MAC + DWORD dwFileType; + DWORD dwCreatorType; + WORD wFinderFlags; + #endif + } WIN32_FIND_DATAW, *PWIN32_FIND_DATAW, *LPWIN32_FIND_DATAW; + + typedef struct _SYSTEMTIME { + WORD wYear; + WORD wMonth; + WORD wDayOfWeek; + WORD wDay; + WORD wHour; + WORD wMinute; + WORD wSecond; + WORD wMilliseconds; + } SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME; + + typedef struct _OVERLAPPED { + ULONG_PTR Internal; + ULONG_PTR InternalHigh; + union { + struct { + DWORD Offset; + DWORD OffsetHigh; + } DUMMYSTRUCTNAME; + VOID *Pointer; + } DUMMYUNIONNAME; + + HANDLE hEvent; + } OVERLAPPED, *LPOVERLAPPED; + + typedef RTL_CRITICAL_SECTION CRITICAL_SECTION; + + #define WAIT_FAILED ((DWORD)0xFFFFFFFF) + #define WAIT_OBJECT_0 ((STATUS_WAIT_0 ) + 0 ) + + #define INFINITE 0xFFFFFFFF // Wait/Synchronisation: Infinite timeout + + #define STD_INPUT_HANDLE ((DWORD)-10) + #define STD_OUTPUT_HANDLE ((DWORD)-11) + #define STD_ERROR_HANDLE ((DWORD)-12) + + #define HANDLE_FLAG_INHERIT 0x00000001 + #define HANDLE_FLAG_PROTECT_FROM_CLOSE 0x00000002 + + // NOTE: MoveFile + #define MOVEFILE_REPLACE_EXISTING 0x00000001 + #define MOVEFILE_COPY_ALLOWED 0x00000002 + + // NOTE: FormatMessageA + #define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100 + #define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200 + #define FORMAT_MESSAGE_FROM_HMODULE 0x00000800 + #define FORMAT_MESSAGE_FROM_SYSTEM 0x00001000 + + // NOTE: CreateProcessW + #define STARTF_USESTDHANDLES 0x00000100 + + extern "C" + { + __declspec(dllimport) BOOL __stdcall MoveFileExW (const WCHAR *lpExistingFileName, const WCHAR *lpNewFileName, DWORD dwFlags); + __declspec(dllimport) BOOL __stdcall CopyFileW (const WCHAR *lpExistingFileName, const WCHAR *lpNewFileName, BOOL bFailIfExists); + __declspec(dllimport) HANDLE __stdcall CreateSemaphoreA(SECURITY_ATTRIBUTES *lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, const CHAR *lpName); + __declspec(dllimport) DWORD __stdcall FormatMessageW (DWORD dwFlags, VOID const *lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, va_list *Arguments); + __declspec(dllimport) HLOCAL __stdcall LocalFree (HLOCAL hMem); + } + + // NOTE: um/stringapiset.h ///////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) int __stdcall MultiByteToWideChar(UINT CodePage, DWORD dwFlags, const CHAR *lpMultiByteStr, int cbMultiByte, WCHAR *lpWideCharStr, int cchWideChar); + __declspec(dllimport) int __stdcall WideCharToMultiByte(UINT CodePage, DWORD dwFlags, const WCHAR *lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, const CHAR *lpDefaultChar, BOOL *lpUsedDefaultChar); + } + + // NOTE: um/fileapi.h ////////////////////////////////////////////////////////////////////////// + #define INVALID_FILE_SIZE ((DWORD)0xFFFFFFFF) + #define INVALID_FILE_ATTRIBUTES ((DWORD)-1) + + // NOTE: CreateFile + #define CREATE_NEW 1 + #define CREATE_ALWAYS 2 + #define OPEN_EXISTING 3 + #define OPEN_ALWAYS 4 + #define TRUNCATE_EXISTING 5 + + typedef struct _WIN32_FILE_ATTRIBUTE_DATA { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + } WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall FlushFileBuffers (HANDLE hFile); + __declspec(dllimport) BOOL __stdcall CreateDirectoryW (const WCHAR *lpPathName, SECURITY_ATTRIBUTES *lpSecurityAttributes); + __declspec(dllimport) BOOL __stdcall RemoveDirectoryW (const WCHAR *lpPathName); + __declspec(dllimport) BOOL __stdcall FindNextFileW (HANDLE hFindFile, WIN32_FIND_DATAW *lpFindFileData); + __declspec(dllimport) BOOL __stdcall FindClose (HANDLE hFindFile); + + __declspec(dllimport) HANDLE __stdcall FindFirstFileExW (const WCHAR *lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, VOID *lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, VOID *lpSearchFilter, DWORD dwAdditionalFlags); + __declspec(dllimport) BOOL __stdcall GetFileAttributesExW(const WCHAR *lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, VOID *lpFileInformation); + __declspec(dllimport) BOOL __stdcall GetFileSizeEx (HANDLE hFile, LARGE_INTEGER *lpFileSize); + __declspec(dllimport) BOOL __stdcall DeleteFileW (const WCHAR *lpFileName); + __declspec(dllimport) HANDLE __stdcall CreateFileW (const WCHAR *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, SECURITY_ATTRIBUTES *lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); + __declspec(dllimport) BOOL __stdcall ReadFile (HANDLE hFile, VOID *lpBuffer, DWORD nNumberOfBytesToRead, DWORD *lpNumberOfBytesRead, OVERLAPPED *lpOverlapped); + __declspec(dllimport) BOOL __stdcall WriteFile (HANDLE hFile, const VOID *lpBuffer, DWORD nNumberOfBytesToWrite, DWORD *lpNumberOfBytesWritten, OVERLAPPED *lpOverlapped); + __declspec(dllimport) BOOL __stdcall GetDiskFreeSpaceExW (WCHAR const *lpDirectoryName, ULARGE_INTEGER *lpFreeBytesAvailableToCaller, ULARGE_INTEGER *lpTotalNumberOfBytes, ULARGE_INTEGER *lpTotalNumberOfFreeBytes); + } + + // NOTE: um/processenv.h /////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) DWORD __stdcall GetCurrentDirectoryW (DWORD nBufferLength, WCHAR *lpBuffer); + __declspec(dllimport) HANDLE __stdcall GetStdHandle (DWORD nStdHandle); + __declspec(dllimport) WCHAR* __stdcall GetEnvironmentStringsW (); + __declspec(dllimport) BOOL __stdcall FreeEnvironmentStringsW(WCHAR *penv); + __declspec(dllimport) DWORD __stdcall GetEnvironmentVariableW(WCHAR const *lpName, WCHAR *lpBuffer, DWORD nSize); + __declspec(dllimport) BOOL __stdcall SetEnvironmentVariableW(WCHAR const *lpName, WCHAR const *lpValue); + } + + // NOTE: um/psapi.h //////////////////////////////////////////////////////////////////////////// + typedef struct _PROCESS_MEMORY_COUNTERS { + DWORD cb; + DWORD PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; + } PROCESS_MEMORY_COUNTERS; + typedef PROCESS_MEMORY_COUNTERS *PPROCESS_MEMORY_COUNTERS; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall GetProcessMemoryInfo(HANDLE Process, PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb); + } + + // NOTE: um/sysinfoapi.h /////////////////////////////////////////////////////////////////////// + typedef struct _SYSTEM_INFO { + union { + DWORD dwOemId; // Obsolete field...do not use + struct { + WORD wProcessorArchitecture; + WORD wReserved; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + DWORD dwPageSize; + VOID *lpMinimumApplicationAddress; + VOID *lpMaximumApplicationAddress; + DWORD_PTR dwActiveProcessorMask; + DWORD dwNumberOfProcessors; + DWORD dwProcessorType; + DWORD dwAllocationGranularity; + WORD wProcessorLevel; + WORD wProcessorRevision; + } SYSTEM_INFO, *LPSYSTEM_INFO; + + extern "C" + { + __declspec(dllimport) VOID __stdcall GetSystemInfo(SYSTEM_INFO *lpSystemInfo); + __declspec(dllimport) VOID __stdcall GetSystemTime(SYSTEMTIME *lpSystemTime); + __declspec(dllimport) VOID __stdcall GetSystemTimeAsFileTime(FILETIME *lpSystemTimeAsFileTime); + __declspec(dllimport) VOID __stdcall GetLocalTime(SYSTEMTIME *lpSystemTime); + } + + // NOTE: um/timezoneapi.h ////////////////////////////////////////////////////////////////////// + typedef struct _TIME_ZONE_INFORMATION { + LONG Bias; + WCHAR StandardName[32]; + SYSTEMTIME StandardDate; + LONG StandardBias; + WCHAR DaylightName[32]; + SYSTEMTIME DaylightDate; + LONG DaylightBias; + } TIME_ZONE_INFORMATION, *PTIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall FileTimeToSystemTime (const FILETIME* lpFileTime, SYSTEMTIME *lpSystemTime); + __declspec(dllimport) BOOL __stdcall SystemTimeToFileTime (const SYSTEMTIME* lpSystemTime, FILETIME *lpFileTime); + __declspec(dllimport) BOOL __stdcall TzSpecificLocalTimeToSystemTime(const TIME_ZONE_INFORMATION* lpTimeZoneInformation, const SYSTEMTIME* lpLocalTime, const LPSYSTEMTIME lpUniversalTime); + } + + // NOTE: shared/windef.h /////////////////////////////////////////////////////////////////////// + typedef struct tagRECT { + LONG left; + LONG top; + LONG right; + LONG bottom; + } RECT; + + struct HWND__ { + int unused; + }; + typedef struct HWND__ *HWND; + + struct DPI_AWARENESS_CONTEXT__ { + int unused; + }; + typedef struct DPI_AWARENESS_CONTEXT__ *DPI_AWARENESS_CONTEXT; + + typedef enum DPI_AWARENESS { + DPI_AWARENESS_INVALID = -1, + DPI_AWARENESS_UNAWARE = 0, + DPI_AWARENESS_SYSTEM_AWARE = 1, + DPI_AWARENESS_PER_MONITOR_AWARE = 2 + } DPI_AWARENESS; + + #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4) + + // NOTE: um/winuser.h ////////////////////////////////////////////////////////////////////////// + typedef struct tagWINDOWPLACEMENT { + UINT length; + UINT flags; + UINT showCmd; + POINT ptMinPosition; + POINT ptMaxPosition; + RECT rcNormalPosition; + #ifdef _MAC + RECT rcDevice; + #endif + } WINDOWPLACEMENT; + typedef WINDOWPLACEMENT *PWINDOWPLACEMENT, *LPWINDOWPLACEMENT; + + #define SW_HIDE 0 + #define SW_NORMAL 1 + #define SW_MAXIMIZE 3 + #define SW_SHOWNOACTIVATE 4 + #define SW_SHOW 5 + #define SW_FORCEMINIMIZE 11 + + extern "C" + { + __declspec(dllimport) BOOL __stdcall GetWindowRect (HWND hWnd, RECT *lpRect); + __declspec(dllimport) BOOL __stdcall SetWindowPos (HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags); + __declspec(dllimport) UINT __stdcall GetWindowModuleFileNameA(HWND hwnd, LPSTR pszFileName, UINT cchFileNameMax); + __declspec(dllimport) BOOL __stdcall ShowWindow (HWND hWnd, int nCmdShow); + __declspec(dllimport) BOOL __stdcall GetWindowPlacement (HWND hWnd, WINDOWPLACEMENT *lpwndpl); + + } + + // NOTE: um/wininet.h ////////////////////////////////////////////////////////////////////////// + typedef WORD INTERNET_PORT; + typedef VOID *HINTERNET; + + // NOTE: um/winhttp.h ////////////////////////////////////////////////////////////////////////// + #define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY 0 + #define WINHTTP_ACCESS_TYPE_NO_PROXY 1 + #define WINHTTP_ACCESS_TYPE_NAMED_PROXY 3 + #define WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY 4 + + #define INTERNET_DEFAULT_PORT 0 // use the protocol-specific default + #define INTERNET_DEFAULT_HTTP_PORT 80 // " " HTTP " + #define INTERNET_DEFAULT_HTTPS_PORT 443 // " " HTTPS " + + // NOTE: WinHttpOpen + #define WINHTTP_FLAG_ASYNC 0x10000000 // this session is asynchronous (where supported) + #define WINHTTP_FLAG_SECURE_DEFAULTS 0x30000000 // note that this flag also forces async + + // NOTE: WinHttpOpenRequest + #define WINHTTP_FLAG_SECURE 0x00800000 // use SSL if applicable (HTTPS) + #define WINHTTP_FLAG_ESCAPE_PERCENT 0x00000004 // if escaping enabled, escape percent as well + #define WINHTTP_FLAG_NULL_CODEPAGE 0x00000008 // assume all symbols are ASCII, use fast convertion + #define WINHTTP_FLAG_ESCAPE_DISABLE 0x00000040 // disable escaping + #define WINHTTP_FLAG_ESCAPE_DISABLE_QUERY 0x00000080 // if escaping enabled escape path part, but do not escape query + #define WINHTTP_FLAG_BYPASS_PROXY_CACHE 0x00000100 // add "pragma: no-cache" request header + #define WINHTTP_FLAG_REFRESH WINHTTP_FLAG_BYPASS_PROXY_CACHE + #define WINHTTP_FLAG_AUTOMATIC_CHUNKING 0x00000200 // Send request without content-length header or chunked TE + + #define WINHTTP_NO_PROXY_NAME NULL + #define WINHTTP_NO_PROXY_BYPASS NULL + + // + // WINHTTP_QUERY_FLAG_NUMBER - if this bit is set in the dwInfoLevel parameter of + // HttpQueryHeader(), then the value of the header will be converted to a number + // before being returned to the caller, if applicable + // + #define WINHTTP_QUERY_FLAG_NUMBER 0x20000000 + + #define WINHTTP_QUERY_MIME_VERSION 0 + #define WINHTTP_QUERY_CONTENT_TYPE 1 + #define WINHTTP_QUERY_CONTENT_TRANSFER_ENCODING 2 + #define WINHTTP_QUERY_CONTENT_ID 3 + #define WINHTTP_QUERY_CONTENT_DESCRIPTION 4 + #define WINHTTP_QUERY_CONTENT_LENGTH 5 + #define WINHTTP_QUERY_CONTENT_LANGUAGE 6 + #define WINHTTP_QUERY_ALLOW 7 + #define WINHTTP_QUERY_PUBLIC 8 + #define WINHTTP_QUERY_DATE 9 + #define WINHTTP_QUERY_EXPIRES 10 + #define WINHTTP_QUERY_LAST_MODIFIED 11 + #define WINHTTP_QUERY_MESSAGE_ID 12 + #define WINHTTP_QUERY_URI 13 + #define WINHTTP_QUERY_DERIVED_FROM 14 + #define WINHTTP_QUERY_COST 15 + #define WINHTTP_QUERY_LINK 16 + #define WINHTTP_QUERY_PRAGMA 17 + #define WINHTTP_QUERY_VERSION 18 // special: part of status line + #define WINHTTP_QUERY_STATUS_CODE 19 // special: part of status line + #define WINHTTP_QUERY_STATUS_TEXT 20 // special: part of status line + #define WINHTTP_QUERY_RAW_HEADERS 21 // special: all headers as ASCIIZ + #define WINHTTP_QUERY_RAW_HEADERS_CRLF 22 // special: all headers + #define WINHTTP_QUERY_CONNECTION 23 + #define WINHTTP_QUERY_ACCEPT 24 + #define WINHTTP_QUERY_ACCEPT_CHARSET 25 + #define WINHTTP_QUERY_ACCEPT_ENCODING 26 + #define WINHTTP_QUERY_ACCEPT_LANGUAGE 27 + #define WINHTTP_QUERY_AUTHORIZATION 28 + #define WINHTTP_QUERY_CONTENT_ENCODING 29 + #define WINHTTP_QUERY_FORWARDED 30 + #define WINHTTP_QUERY_FROM 31 + #define WINHTTP_QUERY_IF_MODIFIED_SINCE 32 + #define WINHTTP_QUERY_LOCATION 33 + #define WINHTTP_QUERY_ORIG_URI 34 + #define WINHTTP_QUERY_REFERER 35 + #define WINHTTP_QUERY_RETRY_AFTER 36 + #define WINHTTP_QUERY_SERVER 37 + #define WINHTTP_QUERY_TITLE 38 + #define WINHTTP_QUERY_USER_AGENT 39 + #define WINHTTP_QUERY_WWW_AUTHENTICATE 40 + #define WINHTTP_QUERY_PROXY_AUTHENTICATE 41 + #define WINHTTP_QUERY_ACCEPT_RANGES 42 + #define WINHTTP_QUERY_SET_COOKIE 43 + #define WINHTTP_QUERY_COOKIE 44 + #define WINHTTP_QUERY_REQUEST_METHOD 45 // special: GET/POST etc. + #define WINHTTP_QUERY_REFRESH 46 + #define WINHTTP_QUERY_CONTENT_DISPOSITION 47 + + // NOTE: WinHttpQueryHeaders prettifiers for optional parameters. + #define WINHTTP_HEADER_NAME_BY_INDEX NULL + #define WINHTTP_NO_OUTPUT_BUFFER NULL + #define WINHTTP_NO_HEADER_INDEX NULL + + // NOTE: Http Response Status Codes + #define HTTP_STATUS_CONTINUE 100 // OK to continue with request + #define HTTP_STATUS_SWITCH_PROTOCOLS 101 // server has switched protocols in upgrade header + + #define HTTP_STATUS_OK 200 // request completed + #define HTTP_STATUS_CREATED 201 // object created, reason = new URI + #define HTTP_STATUS_ACCEPTED 202 // async completion (TBS) + #define HTTP_STATUS_PARTIAL 203 // partial completion + #define HTTP_STATUS_NO_CONTENT 204 // no info to return + #define HTTP_STATUS_RESET_CONTENT 205 // request completed, but clear form + #define HTTP_STATUS_PARTIAL_CONTENT 206 // partial GET fulfilled + #define HTTP_STATUS_WEBDAV_MULTI_STATUS 207 // WebDAV Multi-Status + + #define HTTP_STATUS_AMBIGUOUS 300 // server couldn't decide what to return + #define HTTP_STATUS_MOVED 301 // object permanently moved + #define HTTP_STATUS_REDIRECT 302 // object temporarily moved + #define HTTP_STATUS_REDIRECT_METHOD 303 // redirection w/ new access method + #define HTTP_STATUS_NOT_MODIFIED 304 // if-modified-since was not modified + #define HTTP_STATUS_USE_PROXY 305 // redirection to proxy, location header specifies proxy to use + #define HTTP_STATUS_REDIRECT_KEEP_VERB 307 // HTTP/1.1: keep same verb + #define HTTP_STATUS_PERMANENT_REDIRECT 308 // Object permanently moved keep verb + + #define HTTP_STATUS_BAD_REQUEST 400 // invalid syntax + #define HTTP_STATUS_DENIED 401 // access denied + #define HTTP_STATUS_PAYMENT_REQ 402 // payment required + #define HTTP_STATUS_FORBIDDEN 403 // request forbidden + #define HTTP_STATUS_NOT_FOUND 404 // object not found + #define HTTP_STATUS_BAD_METHOD 405 // method is not allowed + #define HTTP_STATUS_NONE_ACCEPTABLE 406 // no response acceptable to client found + #define HTTP_STATUS_PROXY_AUTH_REQ 407 // proxy authentication required + #define HTTP_STATUS_REQUEST_TIMEOUT 408 // server timed out waiting for request + #define HTTP_STATUS_CONFLICT 409 // user should resubmit with more info + #define HTTP_STATUS_GONE 410 // the resource is no longer available + #define HTTP_STATUS_LENGTH_REQUIRED 411 // the server refused to accept request w/o a length + #define HTTP_STATUS_PRECOND_FAILED 412 // precondition given in request failed + #define HTTP_STATUS_REQUEST_TOO_LARGE 413 // request entity was too large + #define HTTP_STATUS_URI_TOO_LONG 414 // request URI too long + #define HTTP_STATUS_UNSUPPORTED_MEDIA 415 // unsupported media type + #define HTTP_STATUS_RETRY_WITH 449 // retry after doing the appropriate action. + + #define HTTP_STATUS_SERVER_ERROR 500 // internal server error + #define HTTP_STATUS_NOT_SUPPORTED 501 // required not supported + #define HTTP_STATUS_BAD_GATEWAY 502 // error response received from gateway + #define HTTP_STATUS_SERVICE_UNAVAIL 503 // temporarily overloaded + #define HTTP_STATUS_GATEWAY_TIMEOUT 504 // timed out waiting for gateway + #define HTTP_STATUS_VERSION_NOT_SUP 505 // HTTP version not supported + + #define HTTP_STATUS_FIRST HTTP_STATUS_CONTINUE + #define HTTP_STATUS_LAST HTTP_STATUS_VERSION_NOT_SUP + + #define WINHTTP_CALLBACK_STATUS_RESOLVING_NAME 0x00000001 + #define WINHTTP_CALLBACK_STATUS_NAME_RESOLVED 0x00000002 + #define WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER 0x00000004 + #define WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER 0x00000008 + #define WINHTTP_CALLBACK_STATUS_SENDING_REQUEST 0x00000010 + #define WINHTTP_CALLBACK_STATUS_REQUEST_SENT 0x00000020 + #define WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE 0x00000040 + #define WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED 0x00000080 + #define WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION 0x00000100 + #define WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED 0x00000200 + #define WINHTTP_CALLBACK_STATUS_HANDLE_CREATED 0x00000400 + #define WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING 0x00000800 + #define WINHTTP_CALLBACK_STATUS_DETECTING_PROXY 0x00001000 + #define WINHTTP_CALLBACK_STATUS_REDIRECT 0x00004000 + #define WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE 0x00008000 + #define WINHTTP_CALLBACK_STATUS_SECURE_FAILURE 0x00010000 + #define WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE 0x00020000 + #define WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE 0x00040000 + #define WINHTTP_CALLBACK_STATUS_READ_COMPLETE 0x00080000 + #define WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE 0x00100000 + #define WINHTTP_CALLBACK_STATUS_REQUEST_ERROR 0x00200000 + #define WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE 0x00400000 + + #define WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE 0x01000000 + #define WINHTTP_CALLBACK_STATUS_CLOSE_COMPLETE 0x02000000 + #define WINHTTP_CALLBACK_STATUS_SHUTDOWN_COMPLETE 0x04000000 + #define WINHTTP_CALLBACK_STATUS_SETTINGS_WRITE_COMPLETE 0x10000000 + #define WINHTTP_CALLBACK_STATUS_SETTINGS_READ_COMPLETE 0x20000000 + + #define WINHTTP_CALLBACK_FLAG_RESOLVE_NAME (WINHTTP_CALLBACK_STATUS_RESOLVING_NAME | WINHTTP_CALLBACK_STATUS_NAME_RESOLVED) + #define WINHTTP_CALLBACK_FLAG_CONNECT_TO_SERVER (WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER | WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER) + #define WINHTTP_CALLBACK_FLAG_SEND_REQUEST (WINHTTP_CALLBACK_STATUS_SENDING_REQUEST | WINHTTP_CALLBACK_STATUS_REQUEST_SENT) + #define WINHTTP_CALLBACK_FLAG_RECEIVE_RESPONSE (WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE | WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED) + #define WINHTTP_CALLBACK_FLAG_CLOSE_CONNECTION (WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION | WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED) + #define WINHTTP_CALLBACK_FLAG_HANDLES (WINHTTP_CALLBACK_STATUS_HANDLE_CREATED | WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING) + #define WINHTTP_CALLBACK_FLAG_DETECTING_PROXY WINHTTP_CALLBACK_STATUS_DETECTING_PROXY + #define WINHTTP_CALLBACK_FLAG_REDIRECT WINHTTP_CALLBACK_STATUS_REDIRECT + #define WINHTTP_CALLBACK_FLAG_INTERMEDIATE_RESPONSE WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE + #define WINHTTP_CALLBACK_FLAG_SECURE_FAILURE WINHTTP_CALLBACK_STATUS_SECURE_FAILURE + #define WINHTTP_CALLBACK_FLAG_SENDREQUEST_COMPLETE WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE + #define WINHTTP_CALLBACK_FLAG_HEADERS_AVAILABLE WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE + #define WINHTTP_CALLBACK_FLAG_DATA_AVAILABLE WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE + #define WINHTTP_CALLBACK_FLAG_READ_COMPLETE WINHTTP_CALLBACK_STATUS_READ_COMPLETE + #define WINHTTP_CALLBACK_FLAG_WRITE_COMPLETE WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE + #define WINHTTP_CALLBACK_FLAG_REQUEST_ERROR WINHTTP_CALLBACK_STATUS_REQUEST_ERROR + + #define WINHTTP_CALLBACK_FLAG_GETPROXYFORURL_COMPLETE WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE + + #define WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS (WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE \ + | WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE \ + | WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE \ + | WINHTTP_CALLBACK_STATUS_READ_COMPLETE \ + | WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE \ + | WINHTTP_CALLBACK_STATUS_REQUEST_ERROR \ + | WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE) + + #define WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS 0xffffffff + #define WINHTTP_INVALID_STATUS_CALLBACK ((WINHTTP_STATUS_CALLBACK)(-1L)) + + typedef struct _WINHTTP_EXTENDED_HEADER + { + union + { + CHAR const *pwszName; + WCHAR const *pszName; + }; + union + { + WCHAR const *pwszValue; + CHAR const *pszValue; + }; + } WINHTTP_EXTENDED_HEADER, *PWINHTTP_EXTENDED_HEADER; + + typedef struct _WINHTTP_ASYNC_RESULT + { + DWORD *dwResult; // indicates which async API has encountered an error + DWORD dwError; // the error code if the API failed + } WINHTTP_ASYNC_RESULT, *LPWINHTTP_ASYNC_RESULT, *PWINHTTP_ASYNC_RESULT; + + typedef + VOID + (*WINHTTP_STATUS_CALLBACK)( + HINTERNET hInternet, + DWORD *dwContext, + DWORD dwInternetStatus, + VOID *lpvStatusInformation, + DWORD dwStatusInformationLength + ); + + extern "C" + { + __declspec(dllimport) HINTERNET __stdcall WinHttpOpen(WCHAR const *pszAgentW, DWORD dwAccessType, WCHAR const *pszProxyW, WCHAR const *pszProxyBypassW, DWORD dwFlags); + __declspec(dllimport) BOOL __stdcall WinHttpCloseHandle(HINTERNET hInternet); + __declspec(dllimport) HINTERNET __stdcall WinHttpConnect(HINTERNET hSession, WCHAR const *pswzServerName, INTERNET_PORT nServerPort, DWORD dwReserved); + __declspec(dllimport) BOOL __stdcall WinHttpReadData(HINTERNET hRequest, VOID *lpBuffer, DWORD dwNumberOfBytesToRead, DWORD *lpdwNumberOfBytesRead); + __declspec(dllimport) HINTERNET __stdcall WinHttpOpenRequest(HINTERNET hConnect, WCHAR const *pwszVerb, WCHAR const *pwszObjectName, WCHAR const *pwszVersion, WCHAR const *pwszReferrer, WCHAR const *ppwszAcceptTypes, DWORD dwFlags); + __declspec(dllimport) BOOL __stdcall WinHttpSendRequest(HINTERNET hRequest, WCHAR const *lpszHeaders, DWORD dwHeadersLength, VOID *lpOptional, DWORD dwOptionalLength, DWORD dwTotalLength, DWORD_PTR dwContext); + __declspec(dllimport) DWORD __stdcall WinHttpAddRequestHeadersEx(HINTERNET hRequest, DWORD dwModifiers, ULONGLONG ullFlags, ULONGLONG ullExtra, DWORD cHeaders, WINHTTP_EXTENDED_HEADER *pHeaders); + __declspec(dllimport) BOOL __stdcall WinHttpSetCredentials(HINTERNET hRequest, // HINTERNET handle returned by WinHttpOpenRequest. + DWORD AuthTargets, // Only WINHTTP_AUTH_TARGET_SERVER and WINHTTP_AUTH_TARGET_PROXY are supported in this version and they are mutually exclusive + DWORD AuthScheme, // must be one of the supported Auth Schemes returned from WinHttpQueryAuthSchemes() + WCHAR * pwszUserName, // 1) NULL if default creds is to be used, in which case pszPassword will be ignored + WCHAR * pwszPassword, // 1) "" == Blank Password; 2)Parameter ignored if pszUserName is NULL; 3) Invalid to pass in NULL if pszUserName is not NULL + VOID * pAuthParams); + __declspec(dllimport) BOOL __stdcall WinHttpQueryHeaders(HINTERNET hRequest, DWORD dwInfoLevel, WCHAR const *pwszName, VOID *lpBuffer, DWORD *lpdwBufferLength, DWORD *lpdwIndex); + __declspec(dllimport) BOOL __stdcall WinHttpReceiveResponse(HINTERNET hRequest, VOID *lpReserved); + __declspec(dllimport) WINHTTP_STATUS_CALLBACK __stdcall WinHttpSetStatusCallback(HINTERNET hInternet, WINHTTP_STATUS_CALLBACK lpfnInternetCallback, DWORD dwNotificationFlags, DWORD_PTR dwReserved); + } + + // NOTE: um/DbgHelp.h ////////////////////////////////////////////////////////////////////////// + #define SYMOPT_CASE_INSENSITIVE 0x00000001 + #define SYMOPT_UNDNAME 0x00000002 + #define SYMOPT_DEFERRED_LOADS 0x00000004 + #define SYMOPT_NO_CPP 0x00000008 + #define SYMOPT_LOAD_LINES 0x00000010 + #define SYMOPT_OMAP_FIND_NEAREST 0x00000020 + #define SYMOPT_LOAD_ANYTHING 0x00000040 + #define SYMOPT_IGNORE_CVREC 0x00000080 + #define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 + #define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 + #define SYMOPT_EXACT_SYMBOLS 0x00000400 + #define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 + #define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 + #define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 + #define SYMOPT_PUBLICS_ONLY 0x00004000 + #define SYMOPT_NO_PUBLICS 0x00008000 + #define SYMOPT_AUTO_PUBLICS 0x00010000 + #define SYMOPT_NO_IMAGE_SEARCH 0x00020000 + #define SYMOPT_SECURE 0x00040000 + #define SYMOPT_NO_PROMPTS 0x00080000 + #define SYMOPT_OVERWRITE 0x00100000 + #define SYMOPT_IGNORE_IMAGEDIR 0x00200000 + #define SYMOPT_FLAT_DIRECTORY 0x00400000 + #define SYMOPT_FAVOR_COMPRESSED 0x00800000 + #define SYMOPT_ALLOW_ZERO_ADDRESS 0x01000000 + #define SYMOPT_DISABLE_SYMSRV_AUTODETECT 0x02000000 + #define SYMOPT_READONLY_CACHE 0x04000000 + #define SYMOPT_SYMPATH_LAST 0x08000000 + #define SYMOPT_DISABLE_FAST_SYMBOLS 0x10000000 + #define SYMOPT_DISABLE_SYMSRV_TIMEOUT 0x20000000 + #define SYMOPT_DISABLE_SRVSTAR_ON_STARTUP 0x40000000 + #define SYMOPT_DEBUG 0x80000000 + + #define MAX_SYM_NAME 2000 + + typedef enum { + AddrMode1616, + AddrMode1632, + AddrModeReal, + AddrModeFlat + } ADDRESS_MODE; + + typedef struct _tagADDRESS64 { + DWORD64 Offset; + WORD Segment; + ADDRESS_MODE Mode; + } ADDRESS64, *LPADDRESS64; + + + typedef struct _KDHELP64 { + DWORD64 Thread; + DWORD ThCallbackStack; + DWORD ThCallbackBStore; + DWORD NextCallback; + DWORD FramePointer; + DWORD64 KiCallUserMode; + DWORD64 KeUserCallbackDispatcher; + DWORD64 SystemRangeStart; + DWORD64 KiUserExceptionDispatcher; + DWORD64 StackBase; + DWORD64 StackLimit; + DWORD BuildVersion; + DWORD RetpolineStubFunctionTableSize; + DWORD64 RetpolineStubFunctionTable; + DWORD RetpolineStubOffset; + DWORD RetpolineStubSize; + DWORD64 Reserved0[2]; + } KDHELP64, *PKDHELP64; + + typedef struct _tagSTACKFRAME64 { + ADDRESS64 AddrPC; // program counter + ADDRESS64 AddrReturn; // return address + ADDRESS64 AddrFrame; // frame pointer + ADDRESS64 AddrStack; // stack pointer + ADDRESS64 AddrBStore; // backing store pointer + VOID *FuncTableEntry; // pointer to pdata/fpo or NULL + DWORD64 Params[4]; // possible arguments to the function + BOOL Far; // WOW far call + BOOL Virtual; // is this a virtual frame? + DWORD64 Reserved[3]; + KDHELP64 KdHelp; + } STACKFRAME64; + + typedef struct _IMAGEHLP_LINEW64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) + VOID *Key; // internal + DWORD LineNumber; // line number in file + WCHAR *FileName; // full filename + DWORD64 Address; // first instruction of line + } IMAGEHLP_LINEW64; + + typedef struct _SYMBOL_INFOW { + ULONG SizeOfStruct; + ULONG TypeIndex; // Type Index of symbol + ULONG64 Reserved[2]; + ULONG Index; + ULONG Size; + ULONG64 ModBase; // Base Address of module comtaining this symbol + ULONG Flags; + ULONG64 Value; // Value of symbol, ValuePresent should be 1 + ULONG64 Address; // Address of symbol including base address of module + ULONG Register; // register holding value or pointer to value + ULONG Scope; // scope of the symbol + ULONG Tag; // pdb classification + ULONG NameLen; // Actual length of name + ULONG MaxNameLen; + WCHAR Name[1]; // Name of symbol + } SYMBOL_INFOW; + + typedef BOOL (__stdcall READ_PROCESS_MEMORY_ROUTINE64)(HANDLE hProcess, DWORD64 qwBaseAddress, VOID *lpBuffer, DWORD nSize, DWORD *lpNumberOfBytesRead); + typedef VOID * (__stdcall FUNCTION_TABLE_ACCESS_ROUTINE64)(HANDLE ahProcess, DWORD64 AddrBase); + typedef DWORD64(__stdcall GET_MODULE_BASE_ROUTINE64)(HANDLE hProcess, DWORD64 Address); + typedef DWORD64(__stdcall TRANSLATE_ADDRESS_ROUTINE64)(HANDLE hProcess, HANDLE hThread, ADDRESS64 *lpaddr); + + extern "C" + { + __declspec(dllimport) BOOL __stdcall StackWalk64 (DWORD MachineType, HANDLE hProcess, HANDLE hThread, STACKFRAME64 *StackFrame, VOID *ContextRecord, READ_PROCESS_MEMORY_ROUTINE64 *ReadMemoryRoutine, FUNCTION_TABLE_ACCESS_ROUTINE64 *FunctionTableAccessRoutine, GET_MODULE_BASE_ROUTINE64 *GetModuleBaseRoutine, TRANSLATE_ADDRESS_ROUTINE64 *TranslateAddress); + __declspec(dllimport) BOOL __stdcall SymFromAddrW (HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, SYMBOL_INFOW *Symbol); + __declspec(dllimport) VOID * __stdcall SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase); + __declspec(dllimport) BOOL __stdcall SymGetLineFromAddrW64 (HANDLE hProcess, DWORD64 dwAddr, DWORD *pdwDisplacement, IMAGEHLP_LINEW64 *Line); + __declspec(dllimport) DWORD64 __stdcall SymGetModuleBase64 (HANDLE hProcess, DWORD64 qwAddr); + __declspec(dllimport) BOOL __stdcall SymRefreshModuleList (HANDLE hProcess); + }; + + // NOTE: um/errhandlingapi.h /////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) DWORD __stdcall GetLastError(VOID); + } + + // NOTE: um/libloaderapi.h ///////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) HMODULE __stdcall LoadLibraryA (const CHAR *lpLibFileName); + __declspec(dllimport) BOOL __stdcall FreeLibrary (HMODULE hLibModule); + __declspec(dllimport) void * __stdcall GetProcAddress (HMODULE hModule, const CHAR *lpProcName); + __declspec(dllimport) HMODULE __stdcall GetModuleHandleA (const CHAR *lpModuleName); + __declspec(dllimport) DWORD __stdcall GetModuleFileNameW(HMODULE hModule, WCHAR *lpFilename, DWORD nSize); + } + + // NOTE: um/synchapi.h ///////////////////////////////////////////////////////////////////////// + typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE; + + extern "C" + { + __declspec(dllimport) VOID __stdcall InitializeConditionVariable (CONDITION_VARIABLE *ConditionVariable); + __declspec(dllimport) VOID __stdcall WakeConditionVariable (CONDITION_VARIABLE *ConditionVariable); + __declspec(dllimport) VOID __stdcall WakeAllConditionVariable (CONDITION_VARIABLE *ConditionVariable); + __declspec(dllimport) BOOL __stdcall SleepConditionVariableCS (CONDITION_VARIABLE *ConditionVariable, CRITICAL_SECTION *CriticalSection, DWORD dwMilliseconds); + + __declspec(dllimport) VOID __stdcall InitializeCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) VOID __stdcall EnterCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) VOID __stdcall LeaveCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) BOOL __stdcall InitializeCriticalSectionAndSpinCount(CRITICAL_SECTION *lpCriticalSection, DWORD dwSpinCount); + __declspec(dllimport) BOOL __stdcall InitializeCriticalSectionEx (CRITICAL_SECTION *lpCriticalSection, DWORD dwSpinCount, DWORD Flags); + __declspec(dllimport) DWORD __stdcall SetCriticalSectionSpinCount (CRITICAL_SECTION *lpCriticalSection, DWORD dwSpinCount); + __declspec(dllimport) BOOL __stdcall TryEnterCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) VOID __stdcall DeleteCriticalSection (CRITICAL_SECTION *lpCriticalSection); + + __declspec(dllimport) DWORD __stdcall WaitForSingleObject (HANDLE hHandle, DWORD dwMilliseconds); + __declspec(dllimport) BOOL __stdcall ReleaseSemaphore (HANDLE hSemaphore, LONG lReleaseCount, LONG *lpPreviousCount); + __declspec(dllimport) VOID __stdcall Sleep (DWORD dwMilliseconds); + } + + // NOTE: um/profileapi.h /////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall QueryPerformanceCounter (LARGE_INTEGER* lpPerformanceCount); + __declspec(dllimport) BOOL __stdcall QueryPerformanceFrequency(LARGE_INTEGER* lpFrequency); + } + + // NOTE: um/processthreadsapi.h //////////////////////////////////////////////////////////////// + typedef struct _PROCESS_INFORMATION { + HANDLE hProcess; + HANDLE hThread; + DWORD dwProcessId; + DWORD dwThreadId; + } PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION; + + typedef struct _STARTUPINFOW { + DWORD cb; + WCHAR *lpReserved; + WCHAR *lpDesktop; + WCHAR *lpTitle; + DWORD dwX; + DWORD dwY; + DWORD dwXSize; + DWORD dwYSize; + DWORD dwXCountChars; + DWORD dwYCountChars; + DWORD dwFillAttribute; + DWORD dwFlags; + WORD wShowWindow; + WORD cbReserved2; + BYTE *lpReserved2; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; + } STARTUPINFOW, *LPSTARTUPINFOW; + + typedef DWORD (__stdcall *PTHREAD_START_ROUTINE)( + VOID *lpThreadParameter + ); + typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall CreateProcessW (WCHAR const *lpApplicationName, WCHAR *lpCommandLine, SECURITY_ATTRIBUTES *lpProcessAttributes, SECURITY_ATTRIBUTES *lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, VOID *lpEnvironment, WCHAR const *lpCurrentDirectory, STARTUPINFOW *lpStartupInfo, PROCESS_INFORMATION *lpProcessInformation); + __declspec(dllimport) HANDLE __stdcall CreateThread (SECURITY_ATTRIBUTES *lpThreadAttributes, SIZE_T dwStackSize, PTHREAD_START_ROUTINE lpStartAddress, VOID *lpParameter, DWORD dwCreationFlags, DWORD *lpThreadId); + __declspec(dllimport) DWORD __stdcall GetCurrentThreadId(VOID); + __declspec(dllimport) BOOL __stdcall GetExitCodeProcess(HANDLE hProcess, DWORD *lpExitCode); + __declspec(dllimport) void __stdcall ExitProcess (UINT uExitCode); + } + + // NOTE: um/memoryapi.h //////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) VOID * __stdcall VirtualAlloc (VOID *lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect); + __declspec(dllimport) BOOL __stdcall VirtualProtect(VOID *lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD *lpflOldProtect); + __declspec(dllimport) BOOL __stdcall VirtualFree (VOID *lpAddress, SIZE_T dwSize, DWORD dwFreeType); + } + + // NOTE: shared/bcrypt.h /////////////////////////////////////////////////////////////////////// + typedef VOID *BCRYPT_ALG_HANDLE; + typedef LONG NTSTATUS; + + extern "C" + { + __declspec(dllimport) NTSTATUS __stdcall BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *phAlgorithm, const WCHAR *pszAlgId, const WCHAR *pszImplementation, ULONG dwFlags); + __declspec(dllimport) NTSTATUS __stdcall BCryptGenRandom (BCRYPT_ALG_HANDLE hAlgorithm, UCHAR *pbBuffer, ULONG cbBuffer, ULONG dwFlags); + } + + // NOTE: um/shellapi.h ///////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) HINSTANCE __stdcall ShellExecuteA(HWND hwnd, CHAR const *lpOperation, CHAR const *lpFile, CHAR const *lpParameters, CHAR const *lpDirectory, INT nShowCmd); + __declspec(dllimport) HINSTANCE __stdcall ShellExecuteW(HWND hwnd, WCHAR const *lpOperation, WCHAR const *lpFile, WCHAR const *lpParameters, WCHAR const *lpDirectory, INT nShowCmd); + } + + // NOTE: um/debugapi.h ///////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall IsDebuggerPresent(); + } + + // NOTE: um/namedpipeapi.h ///////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall CreatePipe (HANDLE *hReadPipe, HANDLE *hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize); + __declspec(dllimport) BOOL __stdcall PeekNamedPipe(HANDLE hNamedPipe, VOID *lpBuffer, DWORD nBufferSize, DWORD *lpBytesRead, DWORD *lpTotalBytesAvail, DWORD *lpBytesLeftThisMessage); + } + + // NOTE: um/handleapi.h //////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall SetHandleInformation(HANDLE hObject, DWORD dwMask, DWORD dwFlags); + } + + // NOTE: um/commdlg.h ////////////////////////////////////////////////////////////////////////// + typedef UINT_PTR (__stdcall *LPOFNHOOKPROC)(HWND, UINT, WPARAM, LPARAM); + typedef struct tagOFNW { + DWORD lStructSize; + HWND hwndOwner; + HINSTANCE hInstance; + WCHAR const * lpstrFilter; + LPWSTR lpstrCustomFilter; + DWORD nMaxCustFilter; + DWORD nFilterIndex; + LPWSTR lpstrFile; + DWORD nMaxFile; + LPWSTR lpstrFileTitle; + DWORD nMaxFileTitle; + WCHAR const * lpstrInitialDir; + WCHAR const * lpstrTitle; + DWORD Flags; + WORD nFileOffset; + WORD nFileExtension; + WCHAR const * lpstrDefExt; + LPARAM lCustData; + LPOFNHOOKPROC lpfnHook; + WCHAR const * lpTemplateName; + #ifdef _MAC + LPEDITMENU lpEditInfo; + LPCSTR lpstrPrompt; + #endif + #if (_WIN32_WINNT >= 0x0500) + void * pvReserved; + DWORD dwReserved; + DWORD FlagsEx; + #endif // (_WIN32_WINNT >= 0x0500) + } OPENFILENAMEW, *LPOPENFILENAMEW; + + + #define OFN_READONLY 0x00000001 + #define OFN_OVERWRITEPROMPT 0x00000002 + #define OFN_HIDEREADONLY 0x00000004 + #define OFN_NOCHANGEDIR 0x00000008 + #define OFN_SHOWHELP 0x00000010 + #define OFN_ENABLEHOOK 0x00000020 + #define OFN_ENABLETEMPLATE 0x00000040 + #define OFN_ENABLETEMPLATEHANDLE 0x00000080 + #define OFN_NOVALIDATE 0x00000100 + #define OFN_ALLOWMULTISELECT 0x00000200 + #define OFN_EXTENSIONDIFFERENT 0x00000400 + #define OFN_PATHMUSTEXIST 0x00000800 + #define OFN_FILEMUSTEXIST 0x00001000 + #define OFN_CREATEPROMPT 0x00002000 + #define OFN_SHAREAWARE 0x00004000 + #define OFN_NOREADONLYRETURN 0x00008000 + #define OFN_NOTESTFILECREATE 0x00010000 + #define OFN_NONETWORKBUTTON 0x00020000 + #define OFN_NOLONGNAMES 0x00040000 // force no long names for 4.x modules + #if(WINVER >= 0x0400) + #define OFN_EXPLORER 0x00080000 // new look commdlg + #define OFN_NODEREFERENCELINKS 0x00100000 + #define OFN_LONGNAMES 0x00200000 // force long names for 3.x modules + // OFN_ENABLEINCLUDENOTIFY and OFN_ENABLESIZING require + // Windows 2000 or higher to have any effect. + #define OFN_ENABLEINCLUDENOTIFY 0x00400000 // send include message to callback + #define OFN_ENABLESIZING 0x00800000 + #endif /* WINVER >= 0x0400 */ + #if (_WIN32_WINNT >= 0x0500) + #define OFN_DONTADDTORECENT 0x02000000 + #define OFN_FORCESHOWHIDDEN 0x10000000 // Show All files including System and hidden files + #endif // (_WIN32_WINNT >= 0x0500) + + //FlagsEx Values + #if (_WIN32_WINNT >= 0x0500) + #define OFN_EX_NOPLACESBAR 0x00000001 + #endif // (_WIN32_WINNT >= 0x0500) + + extern "C" + { + __declspec(dllimport) BOOL __stdcall GetSaveFileNameW(LPOPENFILENAMEW); + __declspec(dllimport) BOOL __stdcall GetOpenFileNameW(LPOPENFILENAMEW); + } + + // NOTE: um/shlwapi.h ////////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall PathRelativePathToW(WCHAR *pszPath, WCHAR const *pszFrom, DWORD dwAttrFrom, WCHAR const *pszTo, DWORD dwAttrTo); + __declspec(dllimport) BOOL __stdcall PathIsRelativeW(WCHAR *pszPath); + } + + // NOTE: um/pathcch.h ////////////////////////////////////////////////////////////////////////// + typedef enum PATHCCH_OPTIONS + { + PATHCCH_NONE = 0x0, + + // This option allows applications to gain access to long paths. It has two + // different behaviors. For process configured to enable long paths it will allow + // the returned path to be longer than the max path limit that is normally imposed. + // For process that are not this option will convert long paths into the extended + // length DOS device form (with \\?\ prefix) when the path is longer than the limit. + // This form is not length limited by the Win32 file system API on all versions of Windows. + // This second behavior is the same behavior for OSes that don't have the long path feature. + // This can not be specified with PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH. + PATHCCH_ALLOW_LONG_PATHS = 0x01, + + // Can only be used when PATHCCH_ALLOW_LONG_PATHS is specified. This + // Forces the API to treat the caller as long path enabled, independent of the + // process's long name enabled state. Cannot be used with PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS. + PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS = 0x02, + + // Can only be used when PATHCCH_ALLOW_LONG_PATHS is specified. This + // Forces the API to treat the caller as long path disabled, independent of the + // process's long name enabled state. Cannot be used with PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS. + PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS = 0x04, + + // Disable the normalization of path segments that includes removing trailing dots and spaces. + // This enables access to paths that win32 path normalization will block. + PATHCCH_DO_NOT_NORMALIZE_SEGMENTS = 0x08, + + // Convert the input path into the extended length DOS device path form (with the \\?\ prefix) + // if not already in that form. This enables access to paths that are otherwise not addressable + // due to Win32 normalization rules (that can strip trailing dots and spaces) and path + // length limitations. This option implies the same behavior of PATHCCH_DO_NOT_NORMALIZE_SEGMENTS. + // This can not be specified with PATHCCH_ALLOW_LONG_PATHS. + PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH = 0x10, + + // When combining or normalizing a path ensure there is a trailing backslash. + PATHCCH_ENSURE_TRAILING_SLASH = 0x020, + + // Convert forward slashes to back slashes and collapse multiple slashes. + // This is needed to to support sub-path or identity comparisons. + PATHCCH_CANONICALIZE_SLASHES = 0x040, + } PATHCCH_OPTIONS; + + extern "C" + { + __declspec(dllimport) HRESULT __stdcall PathCchCanonicalizeEx(PWSTR pszPathOut, size_t cchPathOut, WCHAR const *pszPathIn, ULONG dwFlags); + }; + + // NOTE: um/errhandlingapi.h /////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) VOID __stdcall RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const ULONG_PTR* lpArguments); + }; + + // NOTE: include/excpt.h /////////////////////////////////////////////////////////////////// + #define EXCEPTION_EXECUTE_HANDLER 1 + #define EXCEPTION_CONTINUE_SEARCH 0 + #define EXCEPTION_CONTINUE_EXECUTION (-1) + + DN_MSVC_WARNING_POP +#endif // !defined(_INC_WINDOWS) +#endif // !defined(DN_OS_WINDOWS_H) + // DN: Single header generator commented out this header => #include "OS/dn_os_w32.h" +#if !defined(DN_OS_WIN32_H) +#define DN_OS_WIN32_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" + // DN: Single header generator commented out this header => #include "dn_os_windows.h" +#if !defined(DN_OS_WINDOWS_H) +#define DN_OS_WINDOWS_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +#if defined(DN_COMPILER_MSVC) || defined(DN_COMPILER_CLANG_CL) + #pragma comment(lib, "bcrypt") + #pragma comment(lib, "winhttp") + #pragma comment(lib, "dbghelp") + #pragma comment(lib, "comdlg32") + #pragma comment(lib, "pathcch") + #pragma comment(lib, "Shell32") // ShellExecuteW + #pragma comment(lib, "shlwapi") +#endif + +#if defined(DN_NO_WINDOWS_H_REPLACEMENT_HEADER) || defined(_INC_WINDOWS) + #define WIN32_LEAN_AND_MEAN + #include // LONG + #include // DN_OS_SecureRNGBytes -> BCryptOpenAlgorithmProvider ... etc + #include // DN_Win_MakeProcessDPIAware -> SetProcessDpiAwareProc + #include // PathRelativePathTO + #include // PathCchCanonicalizeEx + #include // WinHttp* + #include // PROCESS_MEMORY_COUNTERS_EX2 + #include // OPENFILENAMEW + #include +#else + DN_MSVC_WARNING_PUSH + DN_MSVC_WARNING_DISABLE(4201) // warning C4201: nonstandard extension used: nameless struct/union + + // NOTE: basetsd.h ///////////////////////////////////////////////////////////////////////////// + typedef unsigned __int64 ULONG_PTR, *PULONG_PTR; + typedef unsigned __int64 UINT_PTR, *PUINT_PTR; + typedef ULONG_PTR SIZE_T, *PSIZE_T; + typedef __int64 LONG_PTR, *PLONG_PTR; + typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; + typedef unsigned __int64 ULONG64, *PULONG64; + typedef unsigned __int64 DWORD64, *PDWORD64; + + // NOTE: shared/minwindef.h //////////////////////////////////////////////////////////////////// + struct HINSTANCE__ { + int unused; + }; + typedef struct HINSTANCE__ *HINSTANCE; + + typedef unsigned long DWORD; + typedef int BOOL; + typedef int INT; + typedef unsigned long ULONG; + typedef unsigned int UINT; + typedef unsigned short WORD; + typedef unsigned char BYTE; + typedef unsigned char UCHAR; + typedef HINSTANCE HMODULE; /* HMODULEs can be used in place of HINSTANCEs */ + typedef void * HANDLE; + typedef HANDLE HLOCAL; + + typedef unsigned __int64 WPARAM; + typedef LONG_PTR LPARAM; + typedef LONG_PTR LRESULT; + + #define MAX_PATH 260 + + typedef struct _FILETIME { + DWORD dwLowDateTime; + DWORD dwHighDateTime; + } FILETIME, *PFILETIME, *LPFILETIME; + + // NOTE: shared/winerror.h ///////////////////////////////////////////////////////////////////// + // NOTE: GetModuleFileNameW + #define ERROR_INSUFFICIENT_BUFFER 122L // dderror + + // NOTE: um/winnls.h /////////////////////////////////////////////////////////////////////////// + // NOTE: MultiByteToWideChar + #define CP_UTF8 65001 // UTF-8 translation + + // NOTE: um/winnt.h //////////////////////////////////////////////////////////////////////////// + typedef void VOID; + typedef __int64 LONGLONG; + typedef unsigned __int64 ULONGLONG; + typedef void * HANDLE; + typedef char CHAR; + typedef short SHORT; + typedef long LONG; + typedef wchar_t WCHAR; // wc, 16-bit UNICODE character + typedef CHAR * NPSTR, *LPSTR, *PSTR; + typedef WCHAR * NWPSTR, *LPWSTR, *PWSTR; + typedef long HRESULT; + + // NOTE: VirtualAlloc: Allocation Type + #define MEM_RESERVE 0x00002000 + #define MEM_COMMIT 0x00001000 + #define MEM_DECOMMIT 0x00004000 + #define MEM_RELEASE 0x00008000 + + // NOTE: VirtualAlloc: Page Permissions + #define PAGE_NOACCESS 0x01 + #define PAGE_READONLY 0x02 + #define PAGE_READWRITE 0x04 + #define PAGE_GUARD 0x100 + + // NOTE: HeapAlloc + #define HEAP_ZERO_MEMORY 0x00000008 + #define HEAP_NO_SERIALIZE 0x00000001 + #define HEAP_GROWABLE 0x00000002 + #define HEAP_GENERATE_EXCEPTIONS 0x00000004 + #define HEAP_ZERO_MEMORY 0x00000008 + #define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010 + #define HEAP_TAIL_CHECKING_ENABLED 0x00000020 + #define HEAP_FREE_CHECKING_ENABLED 0x00000040 + #define HEAP_DISABLE_COALESCE_ON_FREE 0x00000080 + #define HEAP_CREATE_ALIGN_16 0x00010000 + #define HEAP_CREATE_ENABLE_TRACING 0x00020000 + #define HEAP_CREATE_ENABLE_EXECUTE 0x00040000 + #define HEAP_MAXIMUM_TAG 0x0FFF + #define HEAP_PSEUDO_TAG_FLAG 0x8000 + #define HEAP_TAG_SHIFT 18 + #define HEAP_CREATE_SEGMENT_HEAP 0x00000100 + #define HEAP_CREATE_HARDENED 0x00000200 + + // NOTE: FormatMessageA + #define MAKELANGID(p, s) ((((WORD )(s)) << 10) | (WORD )(p)) + #define LANG_NEUTRAL 0x00 + #define SUBLANG_DEFAULT 0x01 // user default + + // NOTE: CreateFile + #define GENERIC_READ (0x80000000L) + #define GENERIC_WRITE (0x40000000L) + #define GENERIC_EXECUTE (0x20000000L) + #define GENERIC_ALL (0x10000000L) + + #define FILE_APPEND_DATA (0x0004) // file + + // NOTE: CreateFile/FindFirstFile + #define FILE_SHARE_READ 0x00000001 + #define FILE_SHARE_WRITE 0x00000002 + #define FILE_SHARE_DELETE 0x00000004 + + #define FILE_ATTRIBUTE_READONLY 0x00000001 + #define FILE_ATTRIBUTE_HIDDEN 0x00000002 + #define FILE_ATTRIBUTE_SYSTEM 0x00000004 + #define FILE_ATTRIBUTE_DIRECTORY 0x00000010 + #define FILE_ATTRIBUTE_NORMAL 0x00000080 + + // NOTE: STACKFRAME64 + #define IMAGE_FILE_MACHINE_AMD64 0x8664 // AMD64 (K8) + + // NOTE: WaitForSingleObject + #define WAIT_TIMEOUT 258L // dderror + #define STATUS_WAIT_0 ((DWORD )0x00000000L) + #define STATUS_ABANDONED_WAIT_0 ((DWORD )0x00000080L) + + #define S_OK ((HRESULT)0L) + #define S_FALSE ((HRESULT)1L) + + typedef union _ULARGE_INTEGER { + struct { + DWORD LowPart; + DWORD HighPart; + } DUMMYSTRUCTNAME; + struct { + DWORD LowPart; + DWORD HighPart; + } u; + ULONGLONG QuadPart; + } ULARGE_INTEGER; + + typedef union _LARGE_INTEGER { + struct { + DWORD LowPart; + LONG HighPart; + } DUMMYSTRUCTNAME; + struct { + DWORD LowPart; + LONG HighPart; + } u; + LONGLONG QuadPart; + } LARGE_INTEGER; + + typedef struct __declspec(align(16)) _M128A { + ULONGLONG Low; + LONGLONG High; + } M128A, *PM128A; + + typedef struct __declspec(align(16)) _XSAVE_FORMAT { + WORD ControlWord; + WORD StatusWord; + BYTE TagWord; + BYTE Reserved1; + WORD ErrorOpcode; + DWORD ErrorOffset; + WORD ErrorSelector; + WORD Reserved2; + DWORD DataOffset; + WORD DataSelector; + WORD Reserved3; + DWORD MxCsr; + DWORD MxCsr_Mask; + M128A FloatRegisters[8]; + #if defined(_WIN64) + M128A XmmRegisters[16]; + BYTE Reserved4[96]; + #else + M128A XmmRegisters[8]; + BYTE Reserved4[224]; + #endif + } XSAVE_FORMAT, *PXSAVE_FORMAT; + typedef XSAVE_FORMAT XMM_SAVE_AREA32, *PXMM_SAVE_AREA32; + + typedef struct __declspec(align(16)) _CONTEXT { + DWORD64 P1Home; + DWORD64 P2Home; + DWORD64 P3Home; + DWORD64 P4Home; + DWORD64 P5Home; + DWORD64 P6Home; + DWORD ContextFlags; + DWORD MxCsr; + WORD SegCs; + WORD SegDs; + WORD SegEs; + WORD SegFs; + WORD SegGs; + WORD SegSs; + DWORD EFlags; + DWORD64 Dr0; + DWORD64 Dr1; + DWORD64 Dr2; + DWORD64 Dr3; + DWORD64 Dr6; + DWORD64 Dr7; + DWORD64 Rax; + DWORD64 Rcx; + DWORD64 Rdx; + DWORD64 Rbx; + DWORD64 Rsp; + DWORD64 Rbp; + DWORD64 Rsi; + DWORD64 Rdi; + DWORD64 R8; + DWORD64 R9; + DWORD64 R10; + DWORD64 R11; + DWORD64 R12; + DWORD64 R13; + DWORD64 R14; + DWORD64 R15; + DWORD64 Rip; + + union { + XMM_SAVE_AREA32 FltSave; + + struct { + M128A Header[2]; + M128A Legacy[8]; + M128A Xmm0; + M128A Xmm1; + M128A Xmm2; + M128A Xmm3; + M128A Xmm4; + M128A Xmm5; + M128A Xmm6; + M128A Xmm7; + M128A Xmm8; + M128A Xmm9; + M128A Xmm10; + M128A Xmm11; + M128A Xmm12; + M128A Xmm13; + M128A Xmm14; + M128A Xmm15; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + + M128A VectorRegister[26]; + DWORD64 VectorControl; + DWORD64 DebugControl; + DWORD64 LastBranchToRip; + DWORD64 LastBranchFromRip; + DWORD64 LastExceptionToRip; + DWORD64 LastExceptionFromRip; + } CONTEXT; + + typedef struct _LIST_ENTRY { + struct _LIST_ENTRY *Flink; + struct _LIST_ENTRY *Blink; + } LIST_ENTRY, *PLIST_ENTRY, PRLIST_ENTRY; + + typedef struct _RTL_CRITICAL_SECTION_DEBUG { + WORD Type; + WORD CreatorBackTraceIndex; + struct _RTL_CRITICAL_SECTION *CriticalSection; + LIST_ENTRY ProcessLocksList; + DWORD EntryCount; + DWORD ContentionCount; + DWORD Flags; + WORD CreatorBackTraceIndexHigh; + WORD Identifier; + } RTL_CRITICAL_SECTION_DEBUG, *PRTL_CRITICAL_SECTION_DEBUG, RTL_RESOURCE_DEBUG, *PRTL_RESOURCE_DEBUG; + + typedef struct _RTL_CONDITION_VARIABLE { + VOID *Ptr; + } RTL_CONDITION_VARIABLE, *PRTL_CONDITION_VARIABLE; + + #pragma pack(push, 8) + typedef struct _RTL_CRITICAL_SECTION { + PRTL_CRITICAL_SECTION_DEBUG DebugInfo; + + // + // The following three fields control entering and exiting the critical + // section for the resource + // + + LONG LockCount; + LONG RecursionCount; + HANDLE OwningThread; // from the thread's ClientId->UniqueThread + HANDLE LockSemaphore; + ULONG_PTR SpinCount; // force size on 64-bit systems when packed + } RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION; + #pragma pack(pop) + + typedef struct _MODLOAD_DATA { + DWORD ssize; // size of this struct + DWORD ssig; // signature identifying the passed data + VOID *data; // pointer to passed data + DWORD size; // size of passed data + DWORD flags; // options + } MODLOAD_DATA, *PMODLOAD_DATA; + + #define SLMFLAG_VIRTUAL 0x1 + #define SLMFLAG_ALT_INDEX 0x2 + #define SLMFLAG_NO_SYMBOLS 0x4 + + extern "C" + { + __declspec(dllimport) VOID __stdcall RtlCaptureContext(CONTEXT *ContextRecord); + __declspec(dllimport) HANDLE __stdcall GetCurrentProcess(void); + __declspec(dllimport) HANDLE __stdcall GetCurrentThread(void); + __declspec(dllimport) DWORD __stdcall SymSetOptions(DWORD SymOptions); + __declspec(dllimport) BOOL __stdcall SymInitialize(HANDLE hProcess, const CHAR* UserSearchPath, BOOL fInvadeProcess); + __declspec(dllimport) DWORD64 __stdcall SymLoadModuleEx(HANDLE hProcess, HANDLE hFile, CHAR const *ImageName, CHAR const *ModuleName, DWORD64 BaseOfDll, DWORD DllSize, MODLOAD_DATA *Data, DWORD Flags); + __declspec(dllimport) BOOL __stdcall SymUnloadModule64(HANDLE hProcess, DWORD64 BaseOfDll); + } + + // NOTE: um/heapapi.h //////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) HANDLE __stdcall HeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize); + __declspec(dllimport) BOOL __stdcall HeapDestroy(HANDLE hHeap); + __declspec(dllimport) VOID * __stdcall HeapAlloc(HANDLE hHeap, DWORD dwFlags,SIZE_T dwBytes); + __declspec(dllimport) VOID * __stdcall HeapReAlloc(HANDLE hHeap, DWORD dwFlags, VOID *lpMem, SIZE_T dwBytes); + __declspec(dllimport) BOOL __stdcall HeapFree(HANDLE hHeap, DWORD dwFlags, VOID *lpMem); + __declspec(dllimport) SIZE_T __stdcall HeapSize(HANDLE hHeap, DWORD dwFlags, VOID const *lpMem); + __declspec(dllimport) HANDLE __stdcall GetProcessHeap(VOID); + __declspec(dllimport) SIZE_T __stdcall HeapCompact(HANDLE hHeap, DWORD dwFlags); + } + + // NOTE: shared/windef.h //////////////////////////////////////////////////////////////////// + typedef struct tagPOINT + { + LONG x; + LONG y; + } POINT, *PPOINT, *NPPOINT, *LPPOINT; + + // NOTE: handleapi.h /////////////////////////////////////////////////////////////////////////// + #define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1) + + extern "C" + { + __declspec(dllimport) BOOL __stdcall CloseHandle(HANDLE hObject); + } + + // NOTE: consoleapi.h /////////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall WriteConsoleA(HANDLE hConsoleOutput, const VOID* lpBuffer, DWORD nNumberOfCharsToWrite, DWORD *lpNumberOfCharsWritten, VOID *lpReserved); + __declspec(dllimport) BOOL __stdcall AllocConsole(VOID); + __declspec(dllimport) BOOL __stdcall FreeConsole(VOID); + __declspec(dllimport) BOOL __stdcall AttachConsole(DWORD dwProcessId); + __declspec(dllimport) BOOL __stdcall GetConsoleMode(HANDLE hConsoleHandle, DWORD *lpMode); + } + + // NOTE: um/minwinbase.h /////////////////////////////////////////////////////////////////////// + // NOTE: FindFirstFile + #define FIND_FIRST_EX_CASE_SENSITIVE 0x00000001 + #define FIND_FIRST_EX_LARGE_FETCH 0x00000002 + + // NOTE: WaitFor.. + #define WAIT_FAILED ((DWORD)0xFFFFFFFF) + #define WAIT_OBJECT_0 ((STATUS_WAIT_0 ) + 0 ) + #define WAIT_ABANDONED ((STATUS_ABANDONED_WAIT_0 ) + 0 ) + #define WAIT_ABANDONED_0 ((STATUS_ABANDONED_WAIT_0 ) + 0 ) + + // NOTE: CreateProcessW + #define CREATE_UNICODE_ENVIRONMENT 0x00000400 + #define CREATE_NO_WINDOW 0x08000000 + + typedef enum _GET_FILEEX_INFO_LEVELS { + GetFileExInfoStandard, + GetFileExMaxInfoLevel + } GET_FILEEX_INFO_LEVELS; + + typedef struct _SECURITY_ATTRIBUTES { + DWORD nLength; + VOID *lpSecurityDescriptor; + BOOL bInheritHandle; + } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; + + typedef enum _FINDEX_INFO_LEVELS { + FindExInfoStandard, + FindExInfoBasic, + FindExInfoMaxInfoLevel + } FINDEX_INFO_LEVELS; + + typedef enum _FINDEX_SEARCH_OPS { + FindExSearchNameMatch, + FindExSearchLimitToDirectories, + FindExSearchLimitToDevices, + FindExSearchMaxSearchOp + } FINDEX_SEARCH_OPS; + + typedef struct _WIN32_FIND_DATAW { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + DWORD dwReserved0; + DWORD dwReserved1; + WCHAR cFileName[ MAX_PATH ]; + WCHAR cAlternateFileName[ 14 ]; + #ifdef _MAC + DWORD dwFileType; + DWORD dwCreatorType; + WORD wFinderFlags; + #endif + } WIN32_FIND_DATAW, *PWIN32_FIND_DATAW, *LPWIN32_FIND_DATAW; + + typedef struct _SYSTEMTIME { + WORD wYear; + WORD wMonth; + WORD wDayOfWeek; + WORD wDay; + WORD wHour; + WORD wMinute; + WORD wSecond; + WORD wMilliseconds; + } SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME; + + typedef struct _OVERLAPPED { + ULONG_PTR Internal; + ULONG_PTR InternalHigh; + union { + struct { + DWORD Offset; + DWORD OffsetHigh; + } DUMMYSTRUCTNAME; + VOID *Pointer; + } DUMMYUNIONNAME; + + HANDLE hEvent; + } OVERLAPPED, *LPOVERLAPPED; + + typedef RTL_CRITICAL_SECTION CRITICAL_SECTION; + + #define WAIT_FAILED ((DWORD)0xFFFFFFFF) + #define WAIT_OBJECT_0 ((STATUS_WAIT_0 ) + 0 ) + + #define INFINITE 0xFFFFFFFF // Wait/Synchronisation: Infinite timeout + + #define STD_INPUT_HANDLE ((DWORD)-10) + #define STD_OUTPUT_HANDLE ((DWORD)-11) + #define STD_ERROR_HANDLE ((DWORD)-12) + + #define HANDLE_FLAG_INHERIT 0x00000001 + #define HANDLE_FLAG_PROTECT_FROM_CLOSE 0x00000002 + + // NOTE: MoveFile + #define MOVEFILE_REPLACE_EXISTING 0x00000001 + #define MOVEFILE_COPY_ALLOWED 0x00000002 + + // NOTE: FormatMessageA + #define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100 + #define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200 + #define FORMAT_MESSAGE_FROM_HMODULE 0x00000800 + #define FORMAT_MESSAGE_FROM_SYSTEM 0x00001000 + + // NOTE: CreateProcessW + #define STARTF_USESTDHANDLES 0x00000100 + + extern "C" + { + __declspec(dllimport) BOOL __stdcall MoveFileExW (const WCHAR *lpExistingFileName, const WCHAR *lpNewFileName, DWORD dwFlags); + __declspec(dllimport) BOOL __stdcall CopyFileW (const WCHAR *lpExistingFileName, const WCHAR *lpNewFileName, BOOL bFailIfExists); + __declspec(dllimport) HANDLE __stdcall CreateSemaphoreA(SECURITY_ATTRIBUTES *lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, const CHAR *lpName); + __declspec(dllimport) DWORD __stdcall FormatMessageW (DWORD dwFlags, VOID const *lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, va_list *Arguments); + __declspec(dllimport) HLOCAL __stdcall LocalFree (HLOCAL hMem); + } + + // NOTE: um/stringapiset.h ///////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) int __stdcall MultiByteToWideChar(UINT CodePage, DWORD dwFlags, const CHAR *lpMultiByteStr, int cbMultiByte, WCHAR *lpWideCharStr, int cchWideChar); + __declspec(dllimport) int __stdcall WideCharToMultiByte(UINT CodePage, DWORD dwFlags, const WCHAR *lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, const CHAR *lpDefaultChar, BOOL *lpUsedDefaultChar); + } + + // NOTE: um/fileapi.h ////////////////////////////////////////////////////////////////////////// + #define INVALID_FILE_SIZE ((DWORD)0xFFFFFFFF) + #define INVALID_FILE_ATTRIBUTES ((DWORD)-1) + + // NOTE: CreateFile + #define CREATE_NEW 1 + #define CREATE_ALWAYS 2 + #define OPEN_EXISTING 3 + #define OPEN_ALWAYS 4 + #define TRUNCATE_EXISTING 5 + + typedef struct _WIN32_FILE_ATTRIBUTE_DATA { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + } WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall FlushFileBuffers (HANDLE hFile); + __declspec(dllimport) BOOL __stdcall CreateDirectoryW (const WCHAR *lpPathName, SECURITY_ATTRIBUTES *lpSecurityAttributes); + __declspec(dllimport) BOOL __stdcall RemoveDirectoryW (const WCHAR *lpPathName); + __declspec(dllimport) BOOL __stdcall FindNextFileW (HANDLE hFindFile, WIN32_FIND_DATAW *lpFindFileData); + __declspec(dllimport) BOOL __stdcall FindClose (HANDLE hFindFile); + + __declspec(dllimport) HANDLE __stdcall FindFirstFileExW (const WCHAR *lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, VOID *lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, VOID *lpSearchFilter, DWORD dwAdditionalFlags); + __declspec(dllimport) BOOL __stdcall GetFileAttributesExW(const WCHAR *lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, VOID *lpFileInformation); + __declspec(dllimport) BOOL __stdcall GetFileSizeEx (HANDLE hFile, LARGE_INTEGER *lpFileSize); + __declspec(dllimport) BOOL __stdcall DeleteFileW (const WCHAR *lpFileName); + __declspec(dllimport) HANDLE __stdcall CreateFileW (const WCHAR *lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, SECURITY_ATTRIBUTES *lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); + __declspec(dllimport) BOOL __stdcall ReadFile (HANDLE hFile, VOID *lpBuffer, DWORD nNumberOfBytesToRead, DWORD *lpNumberOfBytesRead, OVERLAPPED *lpOverlapped); + __declspec(dllimport) BOOL __stdcall WriteFile (HANDLE hFile, const VOID *lpBuffer, DWORD nNumberOfBytesToWrite, DWORD *lpNumberOfBytesWritten, OVERLAPPED *lpOverlapped); + __declspec(dllimport) BOOL __stdcall GetDiskFreeSpaceExW (WCHAR const *lpDirectoryName, ULARGE_INTEGER *lpFreeBytesAvailableToCaller, ULARGE_INTEGER *lpTotalNumberOfBytes, ULARGE_INTEGER *lpTotalNumberOfFreeBytes); + } + + // NOTE: um/processenv.h /////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) DWORD __stdcall GetCurrentDirectoryW (DWORD nBufferLength, WCHAR *lpBuffer); + __declspec(dllimport) HANDLE __stdcall GetStdHandle (DWORD nStdHandle); + __declspec(dllimport) WCHAR* __stdcall GetEnvironmentStringsW (); + __declspec(dllimport) BOOL __stdcall FreeEnvironmentStringsW(WCHAR *penv); + __declspec(dllimport) DWORD __stdcall GetEnvironmentVariableW(WCHAR const *lpName, WCHAR *lpBuffer, DWORD nSize); + __declspec(dllimport) BOOL __stdcall SetEnvironmentVariableW(WCHAR const *lpName, WCHAR const *lpValue); + } + + // NOTE: um/psapi.h //////////////////////////////////////////////////////////////////////////// + typedef struct _PROCESS_MEMORY_COUNTERS { + DWORD cb; + DWORD PageFaultCount; + SIZE_T PeakWorkingSetSize; + SIZE_T WorkingSetSize; + SIZE_T QuotaPeakPagedPoolUsage; + SIZE_T QuotaPagedPoolUsage; + SIZE_T QuotaPeakNonPagedPoolUsage; + SIZE_T QuotaNonPagedPoolUsage; + SIZE_T PagefileUsage; + SIZE_T PeakPagefileUsage; + } PROCESS_MEMORY_COUNTERS; + typedef PROCESS_MEMORY_COUNTERS *PPROCESS_MEMORY_COUNTERS; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall GetProcessMemoryInfo(HANDLE Process, PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb); + } + + // NOTE: um/sysinfoapi.h /////////////////////////////////////////////////////////////////////// + typedef struct _SYSTEM_INFO { + union { + DWORD dwOemId; // Obsolete field...do not use + struct { + WORD wProcessorArchitecture; + WORD wReserved; + } DUMMYSTRUCTNAME; + } DUMMYUNIONNAME; + DWORD dwPageSize; + VOID *lpMinimumApplicationAddress; + VOID *lpMaximumApplicationAddress; + DWORD_PTR dwActiveProcessorMask; + DWORD dwNumberOfProcessors; + DWORD dwProcessorType; + DWORD dwAllocationGranularity; + WORD wProcessorLevel; + WORD wProcessorRevision; + } SYSTEM_INFO, *LPSYSTEM_INFO; + + extern "C" + { + __declspec(dllimport) VOID __stdcall GetSystemInfo(SYSTEM_INFO *lpSystemInfo); + __declspec(dllimport) VOID __stdcall GetSystemTime(SYSTEMTIME *lpSystemTime); + __declspec(dllimport) VOID __stdcall GetSystemTimeAsFileTime(FILETIME *lpSystemTimeAsFileTime); + __declspec(dllimport) VOID __stdcall GetLocalTime(SYSTEMTIME *lpSystemTime); + } + + // NOTE: um/timezoneapi.h ////////////////////////////////////////////////////////////////////// + typedef struct _TIME_ZONE_INFORMATION { + LONG Bias; + WCHAR StandardName[32]; + SYSTEMTIME StandardDate; + LONG StandardBias; + WCHAR DaylightName[32]; + SYSTEMTIME DaylightDate; + LONG DaylightBias; + } TIME_ZONE_INFORMATION, *PTIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall FileTimeToSystemTime (const FILETIME* lpFileTime, SYSTEMTIME *lpSystemTime); + __declspec(dllimport) BOOL __stdcall SystemTimeToFileTime (const SYSTEMTIME* lpSystemTime, FILETIME *lpFileTime); + __declspec(dllimport) BOOL __stdcall TzSpecificLocalTimeToSystemTime(const TIME_ZONE_INFORMATION* lpTimeZoneInformation, const SYSTEMTIME* lpLocalTime, const LPSYSTEMTIME lpUniversalTime); + } + + // NOTE: shared/windef.h /////////////////////////////////////////////////////////////////////// + typedef struct tagRECT { + LONG left; + LONG top; + LONG right; + LONG bottom; + } RECT; + + struct HWND__ { + int unused; + }; + typedef struct HWND__ *HWND; + + struct DPI_AWARENESS_CONTEXT__ { + int unused; + }; + typedef struct DPI_AWARENESS_CONTEXT__ *DPI_AWARENESS_CONTEXT; + + typedef enum DPI_AWARENESS { + DPI_AWARENESS_INVALID = -1, + DPI_AWARENESS_UNAWARE = 0, + DPI_AWARENESS_SYSTEM_AWARE = 1, + DPI_AWARENESS_PER_MONITOR_AWARE = 2 + } DPI_AWARENESS; + + #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4) + + // NOTE: um/winuser.h ////////////////////////////////////////////////////////////////////////// + typedef struct tagWINDOWPLACEMENT { + UINT length; + UINT flags; + UINT showCmd; + POINT ptMinPosition; + POINT ptMaxPosition; + RECT rcNormalPosition; + #ifdef _MAC + RECT rcDevice; + #endif + } WINDOWPLACEMENT; + typedef WINDOWPLACEMENT *PWINDOWPLACEMENT, *LPWINDOWPLACEMENT; + + #define SW_HIDE 0 + #define SW_NORMAL 1 + #define SW_MAXIMIZE 3 + #define SW_SHOWNOACTIVATE 4 + #define SW_SHOW 5 + #define SW_FORCEMINIMIZE 11 + + extern "C" + { + __declspec(dllimport) BOOL __stdcall GetWindowRect (HWND hWnd, RECT *lpRect); + __declspec(dllimport) BOOL __stdcall SetWindowPos (HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags); + __declspec(dllimport) UINT __stdcall GetWindowModuleFileNameA(HWND hwnd, LPSTR pszFileName, UINT cchFileNameMax); + __declspec(dllimport) BOOL __stdcall ShowWindow (HWND hWnd, int nCmdShow); + __declspec(dllimport) BOOL __stdcall GetWindowPlacement (HWND hWnd, WINDOWPLACEMENT *lpwndpl); + + } + + // NOTE: um/wininet.h ////////////////////////////////////////////////////////////////////////// + typedef WORD INTERNET_PORT; + typedef VOID *HINTERNET; + + // NOTE: um/winhttp.h ////////////////////////////////////////////////////////////////////////// + #define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY 0 + #define WINHTTP_ACCESS_TYPE_NO_PROXY 1 + #define WINHTTP_ACCESS_TYPE_NAMED_PROXY 3 + #define WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY 4 + + #define INTERNET_DEFAULT_PORT 0 // use the protocol-specific default + #define INTERNET_DEFAULT_HTTP_PORT 80 // " " HTTP " + #define INTERNET_DEFAULT_HTTPS_PORT 443 // " " HTTPS " + + // NOTE: WinHttpOpen + #define WINHTTP_FLAG_ASYNC 0x10000000 // this session is asynchronous (where supported) + #define WINHTTP_FLAG_SECURE_DEFAULTS 0x30000000 // note that this flag also forces async + + // NOTE: WinHttpOpenRequest + #define WINHTTP_FLAG_SECURE 0x00800000 // use SSL if applicable (HTTPS) + #define WINHTTP_FLAG_ESCAPE_PERCENT 0x00000004 // if escaping enabled, escape percent as well + #define WINHTTP_FLAG_NULL_CODEPAGE 0x00000008 // assume all symbols are ASCII, use fast convertion + #define WINHTTP_FLAG_ESCAPE_DISABLE 0x00000040 // disable escaping + #define WINHTTP_FLAG_ESCAPE_DISABLE_QUERY 0x00000080 // if escaping enabled escape path part, but do not escape query + #define WINHTTP_FLAG_BYPASS_PROXY_CACHE 0x00000100 // add "pragma: no-cache" request header + #define WINHTTP_FLAG_REFRESH WINHTTP_FLAG_BYPASS_PROXY_CACHE + #define WINHTTP_FLAG_AUTOMATIC_CHUNKING 0x00000200 // Send request without content-length header or chunked TE + + #define WINHTTP_NO_PROXY_NAME NULL + #define WINHTTP_NO_PROXY_BYPASS NULL + + // + // WINHTTP_QUERY_FLAG_NUMBER - if this bit is set in the dwInfoLevel parameter of + // HttpQueryHeader(), then the value of the header will be converted to a number + // before being returned to the caller, if applicable + // + #define WINHTTP_QUERY_FLAG_NUMBER 0x20000000 + + #define WINHTTP_QUERY_MIME_VERSION 0 + #define WINHTTP_QUERY_CONTENT_TYPE 1 + #define WINHTTP_QUERY_CONTENT_TRANSFER_ENCODING 2 + #define WINHTTP_QUERY_CONTENT_ID 3 + #define WINHTTP_QUERY_CONTENT_DESCRIPTION 4 + #define WINHTTP_QUERY_CONTENT_LENGTH 5 + #define WINHTTP_QUERY_CONTENT_LANGUAGE 6 + #define WINHTTP_QUERY_ALLOW 7 + #define WINHTTP_QUERY_PUBLIC 8 + #define WINHTTP_QUERY_DATE 9 + #define WINHTTP_QUERY_EXPIRES 10 + #define WINHTTP_QUERY_LAST_MODIFIED 11 + #define WINHTTP_QUERY_MESSAGE_ID 12 + #define WINHTTP_QUERY_URI 13 + #define WINHTTP_QUERY_DERIVED_FROM 14 + #define WINHTTP_QUERY_COST 15 + #define WINHTTP_QUERY_LINK 16 + #define WINHTTP_QUERY_PRAGMA 17 + #define WINHTTP_QUERY_VERSION 18 // special: part of status line + #define WINHTTP_QUERY_STATUS_CODE 19 // special: part of status line + #define WINHTTP_QUERY_STATUS_TEXT 20 // special: part of status line + #define WINHTTP_QUERY_RAW_HEADERS 21 // special: all headers as ASCIIZ + #define WINHTTP_QUERY_RAW_HEADERS_CRLF 22 // special: all headers + #define WINHTTP_QUERY_CONNECTION 23 + #define WINHTTP_QUERY_ACCEPT 24 + #define WINHTTP_QUERY_ACCEPT_CHARSET 25 + #define WINHTTP_QUERY_ACCEPT_ENCODING 26 + #define WINHTTP_QUERY_ACCEPT_LANGUAGE 27 + #define WINHTTP_QUERY_AUTHORIZATION 28 + #define WINHTTP_QUERY_CONTENT_ENCODING 29 + #define WINHTTP_QUERY_FORWARDED 30 + #define WINHTTP_QUERY_FROM 31 + #define WINHTTP_QUERY_IF_MODIFIED_SINCE 32 + #define WINHTTP_QUERY_LOCATION 33 + #define WINHTTP_QUERY_ORIG_URI 34 + #define WINHTTP_QUERY_REFERER 35 + #define WINHTTP_QUERY_RETRY_AFTER 36 + #define WINHTTP_QUERY_SERVER 37 + #define WINHTTP_QUERY_TITLE 38 + #define WINHTTP_QUERY_USER_AGENT 39 + #define WINHTTP_QUERY_WWW_AUTHENTICATE 40 + #define WINHTTP_QUERY_PROXY_AUTHENTICATE 41 + #define WINHTTP_QUERY_ACCEPT_RANGES 42 + #define WINHTTP_QUERY_SET_COOKIE 43 + #define WINHTTP_QUERY_COOKIE 44 + #define WINHTTP_QUERY_REQUEST_METHOD 45 // special: GET/POST etc. + #define WINHTTP_QUERY_REFRESH 46 + #define WINHTTP_QUERY_CONTENT_DISPOSITION 47 + + // NOTE: WinHttpQueryHeaders prettifiers for optional parameters. + #define WINHTTP_HEADER_NAME_BY_INDEX NULL + #define WINHTTP_NO_OUTPUT_BUFFER NULL + #define WINHTTP_NO_HEADER_INDEX NULL + + // NOTE: Http Response Status Codes + #define HTTP_STATUS_CONTINUE 100 // OK to continue with request + #define HTTP_STATUS_SWITCH_PROTOCOLS 101 // server has switched protocols in upgrade header + + #define HTTP_STATUS_OK 200 // request completed + #define HTTP_STATUS_CREATED 201 // object created, reason = new URI + #define HTTP_STATUS_ACCEPTED 202 // async completion (TBS) + #define HTTP_STATUS_PARTIAL 203 // partial completion + #define HTTP_STATUS_NO_CONTENT 204 // no info to return + #define HTTP_STATUS_RESET_CONTENT 205 // request completed, but clear form + #define HTTP_STATUS_PARTIAL_CONTENT 206 // partial GET fulfilled + #define HTTP_STATUS_WEBDAV_MULTI_STATUS 207 // WebDAV Multi-Status + + #define HTTP_STATUS_AMBIGUOUS 300 // server couldn't decide what to return + #define HTTP_STATUS_MOVED 301 // object permanently moved + #define HTTP_STATUS_REDIRECT 302 // object temporarily moved + #define HTTP_STATUS_REDIRECT_METHOD 303 // redirection w/ new access method + #define HTTP_STATUS_NOT_MODIFIED 304 // if-modified-since was not modified + #define HTTP_STATUS_USE_PROXY 305 // redirection to proxy, location header specifies proxy to use + #define HTTP_STATUS_REDIRECT_KEEP_VERB 307 // HTTP/1.1: keep same verb + #define HTTP_STATUS_PERMANENT_REDIRECT 308 // Object permanently moved keep verb + + #define HTTP_STATUS_BAD_REQUEST 400 // invalid syntax + #define HTTP_STATUS_DENIED 401 // access denied + #define HTTP_STATUS_PAYMENT_REQ 402 // payment required + #define HTTP_STATUS_FORBIDDEN 403 // request forbidden + #define HTTP_STATUS_NOT_FOUND 404 // object not found + #define HTTP_STATUS_BAD_METHOD 405 // method is not allowed + #define HTTP_STATUS_NONE_ACCEPTABLE 406 // no response acceptable to client found + #define HTTP_STATUS_PROXY_AUTH_REQ 407 // proxy authentication required + #define HTTP_STATUS_REQUEST_TIMEOUT 408 // server timed out waiting for request + #define HTTP_STATUS_CONFLICT 409 // user should resubmit with more info + #define HTTP_STATUS_GONE 410 // the resource is no longer available + #define HTTP_STATUS_LENGTH_REQUIRED 411 // the server refused to accept request w/o a length + #define HTTP_STATUS_PRECOND_FAILED 412 // precondition given in request failed + #define HTTP_STATUS_REQUEST_TOO_LARGE 413 // request entity was too large + #define HTTP_STATUS_URI_TOO_LONG 414 // request URI too long + #define HTTP_STATUS_UNSUPPORTED_MEDIA 415 // unsupported media type + #define HTTP_STATUS_RETRY_WITH 449 // retry after doing the appropriate action. + + #define HTTP_STATUS_SERVER_ERROR 500 // internal server error + #define HTTP_STATUS_NOT_SUPPORTED 501 // required not supported + #define HTTP_STATUS_BAD_GATEWAY 502 // error response received from gateway + #define HTTP_STATUS_SERVICE_UNAVAIL 503 // temporarily overloaded + #define HTTP_STATUS_GATEWAY_TIMEOUT 504 // timed out waiting for gateway + #define HTTP_STATUS_VERSION_NOT_SUP 505 // HTTP version not supported + + #define HTTP_STATUS_FIRST HTTP_STATUS_CONTINUE + #define HTTP_STATUS_LAST HTTP_STATUS_VERSION_NOT_SUP + + #define WINHTTP_CALLBACK_STATUS_RESOLVING_NAME 0x00000001 + #define WINHTTP_CALLBACK_STATUS_NAME_RESOLVED 0x00000002 + #define WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER 0x00000004 + #define WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER 0x00000008 + #define WINHTTP_CALLBACK_STATUS_SENDING_REQUEST 0x00000010 + #define WINHTTP_CALLBACK_STATUS_REQUEST_SENT 0x00000020 + #define WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE 0x00000040 + #define WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED 0x00000080 + #define WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION 0x00000100 + #define WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED 0x00000200 + #define WINHTTP_CALLBACK_STATUS_HANDLE_CREATED 0x00000400 + #define WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING 0x00000800 + #define WINHTTP_CALLBACK_STATUS_DETECTING_PROXY 0x00001000 + #define WINHTTP_CALLBACK_STATUS_REDIRECT 0x00004000 + #define WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE 0x00008000 + #define WINHTTP_CALLBACK_STATUS_SECURE_FAILURE 0x00010000 + #define WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE 0x00020000 + #define WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE 0x00040000 + #define WINHTTP_CALLBACK_STATUS_READ_COMPLETE 0x00080000 + #define WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE 0x00100000 + #define WINHTTP_CALLBACK_STATUS_REQUEST_ERROR 0x00200000 + #define WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE 0x00400000 + + #define WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE 0x01000000 + #define WINHTTP_CALLBACK_STATUS_CLOSE_COMPLETE 0x02000000 + #define WINHTTP_CALLBACK_STATUS_SHUTDOWN_COMPLETE 0x04000000 + #define WINHTTP_CALLBACK_STATUS_SETTINGS_WRITE_COMPLETE 0x10000000 + #define WINHTTP_CALLBACK_STATUS_SETTINGS_READ_COMPLETE 0x20000000 + + #define WINHTTP_CALLBACK_FLAG_RESOLVE_NAME (WINHTTP_CALLBACK_STATUS_RESOLVING_NAME | WINHTTP_CALLBACK_STATUS_NAME_RESOLVED) + #define WINHTTP_CALLBACK_FLAG_CONNECT_TO_SERVER (WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER | WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER) + #define WINHTTP_CALLBACK_FLAG_SEND_REQUEST (WINHTTP_CALLBACK_STATUS_SENDING_REQUEST | WINHTTP_CALLBACK_STATUS_REQUEST_SENT) + #define WINHTTP_CALLBACK_FLAG_RECEIVE_RESPONSE (WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE | WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED) + #define WINHTTP_CALLBACK_FLAG_CLOSE_CONNECTION (WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION | WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED) + #define WINHTTP_CALLBACK_FLAG_HANDLES (WINHTTP_CALLBACK_STATUS_HANDLE_CREATED | WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING) + #define WINHTTP_CALLBACK_FLAG_DETECTING_PROXY WINHTTP_CALLBACK_STATUS_DETECTING_PROXY + #define WINHTTP_CALLBACK_FLAG_REDIRECT WINHTTP_CALLBACK_STATUS_REDIRECT + #define WINHTTP_CALLBACK_FLAG_INTERMEDIATE_RESPONSE WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE + #define WINHTTP_CALLBACK_FLAG_SECURE_FAILURE WINHTTP_CALLBACK_STATUS_SECURE_FAILURE + #define WINHTTP_CALLBACK_FLAG_SENDREQUEST_COMPLETE WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE + #define WINHTTP_CALLBACK_FLAG_HEADERS_AVAILABLE WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE + #define WINHTTP_CALLBACK_FLAG_DATA_AVAILABLE WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE + #define WINHTTP_CALLBACK_FLAG_READ_COMPLETE WINHTTP_CALLBACK_STATUS_READ_COMPLETE + #define WINHTTP_CALLBACK_FLAG_WRITE_COMPLETE WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE + #define WINHTTP_CALLBACK_FLAG_REQUEST_ERROR WINHTTP_CALLBACK_STATUS_REQUEST_ERROR + + #define WINHTTP_CALLBACK_FLAG_GETPROXYFORURL_COMPLETE WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE + + #define WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS (WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE \ + | WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE \ + | WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE \ + | WINHTTP_CALLBACK_STATUS_READ_COMPLETE \ + | WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE \ + | WINHTTP_CALLBACK_STATUS_REQUEST_ERROR \ + | WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE) + + #define WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS 0xffffffff + #define WINHTTP_INVALID_STATUS_CALLBACK ((WINHTTP_STATUS_CALLBACK)(-1L)) + + typedef struct _WINHTTP_EXTENDED_HEADER + { + union + { + CHAR const *pwszName; + WCHAR const *pszName; + }; + union + { + WCHAR const *pwszValue; + CHAR const *pszValue; + }; + } WINHTTP_EXTENDED_HEADER, *PWINHTTP_EXTENDED_HEADER; + + typedef struct _WINHTTP_ASYNC_RESULT + { + DWORD *dwResult; // indicates which async API has encountered an error + DWORD dwError; // the error code if the API failed + } WINHTTP_ASYNC_RESULT, *LPWINHTTP_ASYNC_RESULT, *PWINHTTP_ASYNC_RESULT; + + typedef + VOID + (*WINHTTP_STATUS_CALLBACK)( + HINTERNET hInternet, + DWORD *dwContext, + DWORD dwInternetStatus, + VOID *lpvStatusInformation, + DWORD dwStatusInformationLength + ); + + extern "C" + { + __declspec(dllimport) HINTERNET __stdcall WinHttpOpen(WCHAR const *pszAgentW, DWORD dwAccessType, WCHAR const *pszProxyW, WCHAR const *pszProxyBypassW, DWORD dwFlags); + __declspec(dllimport) BOOL __stdcall WinHttpCloseHandle(HINTERNET hInternet); + __declspec(dllimport) HINTERNET __stdcall WinHttpConnect(HINTERNET hSession, WCHAR const *pswzServerName, INTERNET_PORT nServerPort, DWORD dwReserved); + __declspec(dllimport) BOOL __stdcall WinHttpReadData(HINTERNET hRequest, VOID *lpBuffer, DWORD dwNumberOfBytesToRead, DWORD *lpdwNumberOfBytesRead); + __declspec(dllimport) HINTERNET __stdcall WinHttpOpenRequest(HINTERNET hConnect, WCHAR const *pwszVerb, WCHAR const *pwszObjectName, WCHAR const *pwszVersion, WCHAR const *pwszReferrer, WCHAR const *ppwszAcceptTypes, DWORD dwFlags); + __declspec(dllimport) BOOL __stdcall WinHttpSendRequest(HINTERNET hRequest, WCHAR const *lpszHeaders, DWORD dwHeadersLength, VOID *lpOptional, DWORD dwOptionalLength, DWORD dwTotalLength, DWORD_PTR dwContext); + __declspec(dllimport) DWORD __stdcall WinHttpAddRequestHeadersEx(HINTERNET hRequest, DWORD dwModifiers, ULONGLONG ullFlags, ULONGLONG ullExtra, DWORD cHeaders, WINHTTP_EXTENDED_HEADER *pHeaders); + __declspec(dllimport) BOOL __stdcall WinHttpSetCredentials(HINTERNET hRequest, // HINTERNET handle returned by WinHttpOpenRequest. + DWORD AuthTargets, // Only WINHTTP_AUTH_TARGET_SERVER and WINHTTP_AUTH_TARGET_PROXY are supported in this version and they are mutually exclusive + DWORD AuthScheme, // must be one of the supported Auth Schemes returned from WinHttpQueryAuthSchemes() + WCHAR * pwszUserName, // 1) NULL if default creds is to be used, in which case pszPassword will be ignored + WCHAR * pwszPassword, // 1) "" == Blank Password; 2)Parameter ignored if pszUserName is NULL; 3) Invalid to pass in NULL if pszUserName is not NULL + VOID * pAuthParams); + __declspec(dllimport) BOOL __stdcall WinHttpQueryHeaders(HINTERNET hRequest, DWORD dwInfoLevel, WCHAR const *pwszName, VOID *lpBuffer, DWORD *lpdwBufferLength, DWORD *lpdwIndex); + __declspec(dllimport) BOOL __stdcall WinHttpReceiveResponse(HINTERNET hRequest, VOID *lpReserved); + __declspec(dllimport) WINHTTP_STATUS_CALLBACK __stdcall WinHttpSetStatusCallback(HINTERNET hInternet, WINHTTP_STATUS_CALLBACK lpfnInternetCallback, DWORD dwNotificationFlags, DWORD_PTR dwReserved); + } + + // NOTE: um/DbgHelp.h ////////////////////////////////////////////////////////////////////////// + #define SYMOPT_CASE_INSENSITIVE 0x00000001 + #define SYMOPT_UNDNAME 0x00000002 + #define SYMOPT_DEFERRED_LOADS 0x00000004 + #define SYMOPT_NO_CPP 0x00000008 + #define SYMOPT_LOAD_LINES 0x00000010 + #define SYMOPT_OMAP_FIND_NEAREST 0x00000020 + #define SYMOPT_LOAD_ANYTHING 0x00000040 + #define SYMOPT_IGNORE_CVREC 0x00000080 + #define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 + #define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 + #define SYMOPT_EXACT_SYMBOLS 0x00000400 + #define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 + #define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 + #define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 + #define SYMOPT_PUBLICS_ONLY 0x00004000 + #define SYMOPT_NO_PUBLICS 0x00008000 + #define SYMOPT_AUTO_PUBLICS 0x00010000 + #define SYMOPT_NO_IMAGE_SEARCH 0x00020000 + #define SYMOPT_SECURE 0x00040000 + #define SYMOPT_NO_PROMPTS 0x00080000 + #define SYMOPT_OVERWRITE 0x00100000 + #define SYMOPT_IGNORE_IMAGEDIR 0x00200000 + #define SYMOPT_FLAT_DIRECTORY 0x00400000 + #define SYMOPT_FAVOR_COMPRESSED 0x00800000 + #define SYMOPT_ALLOW_ZERO_ADDRESS 0x01000000 + #define SYMOPT_DISABLE_SYMSRV_AUTODETECT 0x02000000 + #define SYMOPT_READONLY_CACHE 0x04000000 + #define SYMOPT_SYMPATH_LAST 0x08000000 + #define SYMOPT_DISABLE_FAST_SYMBOLS 0x10000000 + #define SYMOPT_DISABLE_SYMSRV_TIMEOUT 0x20000000 + #define SYMOPT_DISABLE_SRVSTAR_ON_STARTUP 0x40000000 + #define SYMOPT_DEBUG 0x80000000 + + #define MAX_SYM_NAME 2000 + + typedef enum { + AddrMode1616, + AddrMode1632, + AddrModeReal, + AddrModeFlat + } ADDRESS_MODE; + + typedef struct _tagADDRESS64 { + DWORD64 Offset; + WORD Segment; + ADDRESS_MODE Mode; + } ADDRESS64, *LPADDRESS64; + + + typedef struct _KDHELP64 { + DWORD64 Thread; + DWORD ThCallbackStack; + DWORD ThCallbackBStore; + DWORD NextCallback; + DWORD FramePointer; + DWORD64 KiCallUserMode; + DWORD64 KeUserCallbackDispatcher; + DWORD64 SystemRangeStart; + DWORD64 KiUserExceptionDispatcher; + DWORD64 StackBase; + DWORD64 StackLimit; + DWORD BuildVersion; + DWORD RetpolineStubFunctionTableSize; + DWORD64 RetpolineStubFunctionTable; + DWORD RetpolineStubOffset; + DWORD RetpolineStubSize; + DWORD64 Reserved0[2]; + } KDHELP64, *PKDHELP64; + + typedef struct _tagSTACKFRAME64 { + ADDRESS64 AddrPC; // program counter + ADDRESS64 AddrReturn; // return address + ADDRESS64 AddrFrame; // frame pointer + ADDRESS64 AddrStack; // stack pointer + ADDRESS64 AddrBStore; // backing store pointer + VOID *FuncTableEntry; // pointer to pdata/fpo or NULL + DWORD64 Params[4]; // possible arguments to the function + BOOL Far; // WOW far call + BOOL Virtual; // is this a virtual frame? + DWORD64 Reserved[3]; + KDHELP64 KdHelp; + } STACKFRAME64; + + typedef struct _IMAGEHLP_LINEW64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) + VOID *Key; // internal + DWORD LineNumber; // line number in file + WCHAR *FileName; // full filename + DWORD64 Address; // first instruction of line + } IMAGEHLP_LINEW64; + + typedef struct _SYMBOL_INFOW { + ULONG SizeOfStruct; + ULONG TypeIndex; // Type Index of symbol + ULONG64 Reserved[2]; + ULONG Index; + ULONG Size; + ULONG64 ModBase; // Base Address of module comtaining this symbol + ULONG Flags; + ULONG64 Value; // Value of symbol, ValuePresent should be 1 + ULONG64 Address; // Address of symbol including base address of module + ULONG Register; // register holding value or pointer to value + ULONG Scope; // scope of the symbol + ULONG Tag; // pdb classification + ULONG NameLen; // Actual length of name + ULONG MaxNameLen; + WCHAR Name[1]; // Name of symbol + } SYMBOL_INFOW; + + typedef BOOL (__stdcall READ_PROCESS_MEMORY_ROUTINE64)(HANDLE hProcess, DWORD64 qwBaseAddress, VOID *lpBuffer, DWORD nSize, DWORD *lpNumberOfBytesRead); + typedef VOID * (__stdcall FUNCTION_TABLE_ACCESS_ROUTINE64)(HANDLE ahProcess, DWORD64 AddrBase); + typedef DWORD64(__stdcall GET_MODULE_BASE_ROUTINE64)(HANDLE hProcess, DWORD64 Address); + typedef DWORD64(__stdcall TRANSLATE_ADDRESS_ROUTINE64)(HANDLE hProcess, HANDLE hThread, ADDRESS64 *lpaddr); + + extern "C" + { + __declspec(dllimport) BOOL __stdcall StackWalk64 (DWORD MachineType, HANDLE hProcess, HANDLE hThread, STACKFRAME64 *StackFrame, VOID *ContextRecord, READ_PROCESS_MEMORY_ROUTINE64 *ReadMemoryRoutine, FUNCTION_TABLE_ACCESS_ROUTINE64 *FunctionTableAccessRoutine, GET_MODULE_BASE_ROUTINE64 *GetModuleBaseRoutine, TRANSLATE_ADDRESS_ROUTINE64 *TranslateAddress); + __declspec(dllimport) BOOL __stdcall SymFromAddrW (HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, SYMBOL_INFOW *Symbol); + __declspec(dllimport) VOID * __stdcall SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase); + __declspec(dllimport) BOOL __stdcall SymGetLineFromAddrW64 (HANDLE hProcess, DWORD64 dwAddr, DWORD *pdwDisplacement, IMAGEHLP_LINEW64 *Line); + __declspec(dllimport) DWORD64 __stdcall SymGetModuleBase64 (HANDLE hProcess, DWORD64 qwAddr); + __declspec(dllimport) BOOL __stdcall SymRefreshModuleList (HANDLE hProcess); + }; + + // NOTE: um/errhandlingapi.h /////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) DWORD __stdcall GetLastError(VOID); + } + + // NOTE: um/libloaderapi.h ///////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) HMODULE __stdcall LoadLibraryA (const CHAR *lpLibFileName); + __declspec(dllimport) BOOL __stdcall FreeLibrary (HMODULE hLibModule); + __declspec(dllimport) void * __stdcall GetProcAddress (HMODULE hModule, const CHAR *lpProcName); + __declspec(dllimport) HMODULE __stdcall GetModuleHandleA (const CHAR *lpModuleName); + __declspec(dllimport) DWORD __stdcall GetModuleFileNameW(HMODULE hModule, WCHAR *lpFilename, DWORD nSize); + } + + // NOTE: um/synchapi.h ///////////////////////////////////////////////////////////////////////// + typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE; + + extern "C" + { + __declspec(dllimport) VOID __stdcall InitializeConditionVariable (CONDITION_VARIABLE *ConditionVariable); + __declspec(dllimport) VOID __stdcall WakeConditionVariable (CONDITION_VARIABLE *ConditionVariable); + __declspec(dllimport) VOID __stdcall WakeAllConditionVariable (CONDITION_VARIABLE *ConditionVariable); + __declspec(dllimport) BOOL __stdcall SleepConditionVariableCS (CONDITION_VARIABLE *ConditionVariable, CRITICAL_SECTION *CriticalSection, DWORD dwMilliseconds); + + __declspec(dllimport) VOID __stdcall InitializeCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) VOID __stdcall EnterCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) VOID __stdcall LeaveCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) BOOL __stdcall InitializeCriticalSectionAndSpinCount(CRITICAL_SECTION *lpCriticalSection, DWORD dwSpinCount); + __declspec(dllimport) BOOL __stdcall InitializeCriticalSectionEx (CRITICAL_SECTION *lpCriticalSection, DWORD dwSpinCount, DWORD Flags); + __declspec(dllimport) DWORD __stdcall SetCriticalSectionSpinCount (CRITICAL_SECTION *lpCriticalSection, DWORD dwSpinCount); + __declspec(dllimport) BOOL __stdcall TryEnterCriticalSection (CRITICAL_SECTION *lpCriticalSection); + __declspec(dllimport) VOID __stdcall DeleteCriticalSection (CRITICAL_SECTION *lpCriticalSection); + + __declspec(dllimport) DWORD __stdcall WaitForSingleObject (HANDLE hHandle, DWORD dwMilliseconds); + __declspec(dllimport) BOOL __stdcall ReleaseSemaphore (HANDLE hSemaphore, LONG lReleaseCount, LONG *lpPreviousCount); + __declspec(dllimport) VOID __stdcall Sleep (DWORD dwMilliseconds); + } + + // NOTE: um/profileapi.h /////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall QueryPerformanceCounter (LARGE_INTEGER* lpPerformanceCount); + __declspec(dllimport) BOOL __stdcall QueryPerformanceFrequency(LARGE_INTEGER* lpFrequency); + } + + // NOTE: um/processthreadsapi.h //////////////////////////////////////////////////////////////// + typedef struct _PROCESS_INFORMATION { + HANDLE hProcess; + HANDLE hThread; + DWORD dwProcessId; + DWORD dwThreadId; + } PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION; + + typedef struct _STARTUPINFOW { + DWORD cb; + WCHAR *lpReserved; + WCHAR *lpDesktop; + WCHAR *lpTitle; + DWORD dwX; + DWORD dwY; + DWORD dwXSize; + DWORD dwYSize; + DWORD dwXCountChars; + DWORD dwYCountChars; + DWORD dwFillAttribute; + DWORD dwFlags; + WORD wShowWindow; + WORD cbReserved2; + BYTE *lpReserved2; + HANDLE hStdInput; + HANDLE hStdOutput; + HANDLE hStdError; + } STARTUPINFOW, *LPSTARTUPINFOW; + + typedef DWORD (__stdcall *PTHREAD_START_ROUTINE)( + VOID *lpThreadParameter + ); + typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE; + + extern "C" + { + __declspec(dllimport) BOOL __stdcall CreateProcessW (WCHAR const *lpApplicationName, WCHAR *lpCommandLine, SECURITY_ATTRIBUTES *lpProcessAttributes, SECURITY_ATTRIBUTES *lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, VOID *lpEnvironment, WCHAR const *lpCurrentDirectory, STARTUPINFOW *lpStartupInfo, PROCESS_INFORMATION *lpProcessInformation); + __declspec(dllimport) HANDLE __stdcall CreateThread (SECURITY_ATTRIBUTES *lpThreadAttributes, SIZE_T dwStackSize, PTHREAD_START_ROUTINE lpStartAddress, VOID *lpParameter, DWORD dwCreationFlags, DWORD *lpThreadId); + __declspec(dllimport) DWORD __stdcall GetCurrentThreadId(VOID); + __declspec(dllimport) BOOL __stdcall GetExitCodeProcess(HANDLE hProcess, DWORD *lpExitCode); + __declspec(dllimport) void __stdcall ExitProcess (UINT uExitCode); + } + + // NOTE: um/memoryapi.h //////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) VOID * __stdcall VirtualAlloc (VOID *lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect); + __declspec(dllimport) BOOL __stdcall VirtualProtect(VOID *lpAddress, SIZE_T dwSize, DWORD flNewProtect, DWORD *lpflOldProtect); + __declspec(dllimport) BOOL __stdcall VirtualFree (VOID *lpAddress, SIZE_T dwSize, DWORD dwFreeType); + } + + // NOTE: shared/bcrypt.h /////////////////////////////////////////////////////////////////////// + typedef VOID *BCRYPT_ALG_HANDLE; + typedef LONG NTSTATUS; + + extern "C" + { + __declspec(dllimport) NTSTATUS __stdcall BCryptOpenAlgorithmProvider(BCRYPT_ALG_HANDLE *phAlgorithm, const WCHAR *pszAlgId, const WCHAR *pszImplementation, ULONG dwFlags); + __declspec(dllimport) NTSTATUS __stdcall BCryptGenRandom (BCRYPT_ALG_HANDLE hAlgorithm, UCHAR *pbBuffer, ULONG cbBuffer, ULONG dwFlags); + } + + // NOTE: um/shellapi.h ///////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) HINSTANCE __stdcall ShellExecuteA(HWND hwnd, CHAR const *lpOperation, CHAR const *lpFile, CHAR const *lpParameters, CHAR const *lpDirectory, INT nShowCmd); + __declspec(dllimport) HINSTANCE __stdcall ShellExecuteW(HWND hwnd, WCHAR const *lpOperation, WCHAR const *lpFile, WCHAR const *lpParameters, WCHAR const *lpDirectory, INT nShowCmd); + } + + // NOTE: um/debugapi.h ///////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall IsDebuggerPresent(); + } + + // NOTE: um/namedpipeapi.h ///////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall CreatePipe (HANDLE *hReadPipe, HANDLE *hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize); + __declspec(dllimport) BOOL __stdcall PeekNamedPipe(HANDLE hNamedPipe, VOID *lpBuffer, DWORD nBufferSize, DWORD *lpBytesRead, DWORD *lpTotalBytesAvail, DWORD *lpBytesLeftThisMessage); + } + + // NOTE: um/handleapi.h //////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall SetHandleInformation(HANDLE hObject, DWORD dwMask, DWORD dwFlags); + } + + // NOTE: um/commdlg.h ////////////////////////////////////////////////////////////////////////// + typedef UINT_PTR (__stdcall *LPOFNHOOKPROC)(HWND, UINT, WPARAM, LPARAM); + typedef struct tagOFNW { + DWORD lStructSize; + HWND hwndOwner; + HINSTANCE hInstance; + WCHAR const * lpstrFilter; + LPWSTR lpstrCustomFilter; + DWORD nMaxCustFilter; + DWORD nFilterIndex; + LPWSTR lpstrFile; + DWORD nMaxFile; + LPWSTR lpstrFileTitle; + DWORD nMaxFileTitle; + WCHAR const * lpstrInitialDir; + WCHAR const * lpstrTitle; + DWORD Flags; + WORD nFileOffset; + WORD nFileExtension; + WCHAR const * lpstrDefExt; + LPARAM lCustData; + LPOFNHOOKPROC lpfnHook; + WCHAR const * lpTemplateName; + #ifdef _MAC + LPEDITMENU lpEditInfo; + LPCSTR lpstrPrompt; + #endif + #if (_WIN32_WINNT >= 0x0500) + void * pvReserved; + DWORD dwReserved; + DWORD FlagsEx; + #endif // (_WIN32_WINNT >= 0x0500) + } OPENFILENAMEW, *LPOPENFILENAMEW; + + + #define OFN_READONLY 0x00000001 + #define OFN_OVERWRITEPROMPT 0x00000002 + #define OFN_HIDEREADONLY 0x00000004 + #define OFN_NOCHANGEDIR 0x00000008 + #define OFN_SHOWHELP 0x00000010 + #define OFN_ENABLEHOOK 0x00000020 + #define OFN_ENABLETEMPLATE 0x00000040 + #define OFN_ENABLETEMPLATEHANDLE 0x00000080 + #define OFN_NOVALIDATE 0x00000100 + #define OFN_ALLOWMULTISELECT 0x00000200 + #define OFN_EXTENSIONDIFFERENT 0x00000400 + #define OFN_PATHMUSTEXIST 0x00000800 + #define OFN_FILEMUSTEXIST 0x00001000 + #define OFN_CREATEPROMPT 0x00002000 + #define OFN_SHAREAWARE 0x00004000 + #define OFN_NOREADONLYRETURN 0x00008000 + #define OFN_NOTESTFILECREATE 0x00010000 + #define OFN_NONETWORKBUTTON 0x00020000 + #define OFN_NOLONGNAMES 0x00040000 // force no long names for 4.x modules + #if(WINVER >= 0x0400) + #define OFN_EXPLORER 0x00080000 // new look commdlg + #define OFN_NODEREFERENCELINKS 0x00100000 + #define OFN_LONGNAMES 0x00200000 // force long names for 3.x modules + // OFN_ENABLEINCLUDENOTIFY and OFN_ENABLESIZING require + // Windows 2000 or higher to have any effect. + #define OFN_ENABLEINCLUDENOTIFY 0x00400000 // send include message to callback + #define OFN_ENABLESIZING 0x00800000 + #endif /* WINVER >= 0x0400 */ + #if (_WIN32_WINNT >= 0x0500) + #define OFN_DONTADDTORECENT 0x02000000 + #define OFN_FORCESHOWHIDDEN 0x10000000 // Show All files including System and hidden files + #endif // (_WIN32_WINNT >= 0x0500) + + //FlagsEx Values + #if (_WIN32_WINNT >= 0x0500) + #define OFN_EX_NOPLACESBAR 0x00000001 + #endif // (_WIN32_WINNT >= 0x0500) + + extern "C" + { + __declspec(dllimport) BOOL __stdcall GetSaveFileNameW(LPOPENFILENAMEW); + __declspec(dllimport) BOOL __stdcall GetOpenFileNameW(LPOPENFILENAMEW); + } + + // NOTE: um/shlwapi.h ////////////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) BOOL __stdcall PathRelativePathToW(WCHAR *pszPath, WCHAR const *pszFrom, DWORD dwAttrFrom, WCHAR const *pszTo, DWORD dwAttrTo); + __declspec(dllimport) BOOL __stdcall PathIsRelativeW(WCHAR *pszPath); + } + + // NOTE: um/pathcch.h ////////////////////////////////////////////////////////////////////////// + typedef enum PATHCCH_OPTIONS + { + PATHCCH_NONE = 0x0, + + // This option allows applications to gain access to long paths. It has two + // different behaviors. For process configured to enable long paths it will allow + // the returned path to be longer than the max path limit that is normally imposed. + // For process that are not this option will convert long paths into the extended + // length DOS device form (with \\?\ prefix) when the path is longer than the limit. + // This form is not length limited by the Win32 file system API on all versions of Windows. + // This second behavior is the same behavior for OSes that don't have the long path feature. + // This can not be specified with PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH. + PATHCCH_ALLOW_LONG_PATHS = 0x01, + + // Can only be used when PATHCCH_ALLOW_LONG_PATHS is specified. This + // Forces the API to treat the caller as long path enabled, independent of the + // process's long name enabled state. Cannot be used with PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS. + PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS = 0x02, + + // Can only be used when PATHCCH_ALLOW_LONG_PATHS is specified. This + // Forces the API to treat the caller as long path disabled, independent of the + // process's long name enabled state. Cannot be used with PATHCCH_FORCE_ENABLE_LONG_NAME_PROCESS. + PATHCCH_FORCE_DISABLE_LONG_NAME_PROCESS = 0x04, + + // Disable the normalization of path segments that includes removing trailing dots and spaces. + // This enables access to paths that win32 path normalization will block. + PATHCCH_DO_NOT_NORMALIZE_SEGMENTS = 0x08, + + // Convert the input path into the extended length DOS device path form (with the \\?\ prefix) + // if not already in that form. This enables access to paths that are otherwise not addressable + // due to Win32 normalization rules (that can strip trailing dots and spaces) and path + // length limitations. This option implies the same behavior of PATHCCH_DO_NOT_NORMALIZE_SEGMENTS. + // This can not be specified with PATHCCH_ALLOW_LONG_PATHS. + PATHCCH_ENSURE_IS_EXTENDED_LENGTH_PATH = 0x10, + + // When combining or normalizing a path ensure there is a trailing backslash. + PATHCCH_ENSURE_TRAILING_SLASH = 0x020, + + // Convert forward slashes to back slashes and collapse multiple slashes. + // This is needed to to support sub-path or identity comparisons. + PATHCCH_CANONICALIZE_SLASHES = 0x040, + } PATHCCH_OPTIONS; + + extern "C" + { + __declspec(dllimport) HRESULT __stdcall PathCchCanonicalizeEx(PWSTR pszPathOut, size_t cchPathOut, WCHAR const *pszPathIn, ULONG dwFlags); + }; + + // NOTE: um/errhandlingapi.h /////////////////////////////////////////////////////////////////// + extern "C" + { + __declspec(dllimport) VOID __stdcall RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, const ULONG_PTR* lpArguments); + }; + + // NOTE: include/excpt.h /////////////////////////////////////////////////////////////////// + #define EXCEPTION_EXECUTE_HANDLER 1 + #define EXCEPTION_CONTINUE_SEARCH 0 + #define EXCEPTION_CONTINUE_EXECUTION (-1) + + DN_MSVC_WARNING_POP +#endif // !defined(_INC_WINDOWS) +#endif // !defined(DN_OS_WINDOWS_H) +#endif + +struct DN_W32Error +{ + unsigned long code; + DN_Str8 msg; +}; + +struct DN_W32FolderIteratorW +{ + void *handle; + DN_Str16 file_name; + wchar_t file_name_buf[512]; +}; + +enum DN_W32SyncPrimitiveType +{ + DN_OSW32SyncPrimitiveType_Semaphore, + DN_OSW32SyncPrimitiveType_Mutex, + DN_OSW32SyncPrimitiveType_ConditionVariable, +}; + +struct DN_W32SyncPrimitive +{ + union + { + void *sem; + CRITICAL_SECTION mutex; + CONDITION_VARIABLE cv; + }; + + DN_W32SyncPrimitive *next; +}; + +typedef HRESULT DN_W32SetThreadDescriptionFunc(HANDLE hThread, PWSTR const lpThreadDescription); +struct DN_W32Core +{ + DN_W32SetThreadDescriptionFunc *set_thread_description; + LARGE_INTEGER qpc_frequency; + void *bcrypt_rng_handle; + bool bcrypt_init_success; + bool sym_initialised; + + CRITICAL_SECTION sync_primitive_free_list_mutex; + DN_W32SyncPrimitive *sync_primitive_free_list; +}; + +DN_API void DN_W32_ThreadSetName (DN_Str8 name); + +DN_API DN_Str16 DN_W32_ErrorCodeToMsg16Alloc(DN_U32 error_code); +DN_API DN_W32Error DN_W32_ErrorCodeToMsg (DN_Arena *arena, DN_U32 error_code); +DN_API DN_W32Error DN_W32_ErrorCodeToMsgAlloc (DN_U32 error_code); +DN_API DN_W32Error DN_W32_LastError (DN_Arena *arena); +DN_API DN_W32Error DN_W32_LastErrorAlloc (); +DN_API void DN_W32_MakeProcessDPIAware (); + +// NOTE: Windows Str8 <-> Str16 //////////////////////////////////////////////////////////////////// +DN_API DN_Str16 DN_W32_Str8ToStr16 (DN_Arena *arena, DN_Str8 src); +DN_API int DN_W32_Str8ToStr16Buffer (DN_Str16 src, char *dest, int dest_size); +DN_API DN_Str8 DN_W32_Str16ToStr8 (DN_Arena *arena, DN_Str16 src); +DN_API int DN_W32_Str16ToStr8Buffer (DN_Str16 src, char *dest, int dest_size); +DN_API DN_Str8 DN_W32_Str16ToStr8FromHeap(DN_Str16 src); + +// NOTE: Path navigation /////////////////////////////////////////////////////////////////////////// +DN_API DN_Str16 DN_W32_EXEPathW (DN_Arena *arena); +DN_API DN_Str16 DN_W32_EXEDirW (DN_Arena *arena); +DN_API DN_Str8 DN_W32_WorkingDir (DN_Arena *arena, DN_Str8 suffix); +DN_API DN_Str16 DN_W32_WorkingDirW (DN_Arena *arena, DN_Str16 suffix); +DN_API bool DN_W32_DirWIterate (DN_Str16 path, DN_W32FolderIteratorW *it); +#endif // !defined(DN_OS_WIN32) +#elif defined(DN_PLATFORM_POSIX) || defined(DN_PLATFORM_EMSCRIPTEN) + // DN: Single header generator commented out this header => #include "OS/dn_os_posix.h" +#if !defined(DN_OS_POSIX_H) +#define DN_OS_POSIX_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +#include +#include + +/* +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// $$$$$$\ $$$$$$\ $$$$$$$\ $$$$$$\ $$$$$$\ $$$$$$\ $$\ $$\ +// $$ __$$\ $$ __$$\ $$ __$$\ $$ __$$\ $$ __$$\ \_$$ _|$$ | $$ | +// $$ / $$ |$$ / \__| $$ | $$ |$$ / $$ |$$ / \__| $$ | \$$\ $$ | +// $$ | $$ |\$$$$$$\ $$$$$$$ |$$ | $$ |\$$$$$$\ $$ | \$$$$ / +// $$ | $$ | \____$$\ $$ ____/ $$ | $$ | \____$$\ $$ | $$ $$< +// $$ | $$ |$$\ $$ | $$ | $$ | $$ |$$\ $$ | $$ | $$ /\$$\ +// $$$$$$ |\$$$$$$ | $$ | $$$$$$ |\$$$$$$ |$$$$$$\ $$ / $$ | +// \______/ \______/ \__| \______/ \______/ \______|\__| \__| +// +// dn_os_posix.h +// +//////////////////////////////////////////////////////////////////////////////////////////////////// +*/ + +struct DN_POSIXProcSelfStatus +{ + char name[64]; + DN_U8 name_size; + DN_U32 pid; + DN_U64 vm_peak; + DN_U32 vm_size; +}; + +// NOTE: The POSIX implementation disallows copies of synchronisation objects in +// general hence we have to dynamically allocate these primitives to maintain a +// consistent address. +// +// +// Source: The Open Group Base Specifications Issue 7, 2018 edition +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_09 +// +// 2.9.9 Synchronization Object Copies and Alternative Mappings +// +// For barriers, condition variables, mutexes, and read-write locks, [TSH] +// [Option Start] if the process-shared attribute is set to +// PTHREAD_PROCESS_PRIVATE, [Option End] only the synchronization object at the +// address used to initialize it can be used for performing synchronization. The +// effect of referring to another mapping of the same object when locking, +// unlocking, or destroying the object is undefined. [...] The effect of +// referring to a copy of the object when locking, unlocking, or destroying it +// is undefined. + +enum DN_POSIXSyncPrimitiveType +{ + DN_OSPOSIXSyncPrimitiveType_Semaphore, + DN_OSPOSIXSyncPrimitiveType_Mutex, + DN_OSPOSIXSyncPrimitiveType_ConditionVariable, +}; + +struct DN_POSIXSyncPrimitive +{ + union + { + sem_t sem; + pthread_mutex_t mutex; + pthread_cond_t cv; + }; + DN_POSIXSyncPrimitive *next; +}; + +struct DN_POSIXCore +{ + DN_POSIXSyncPrimitive *sync_primitive_free_list; + pthread_mutex_t sync_primitive_free_list_mutex; + bool clock_monotonic_raw; +}; + +DN_API void DN_Posix_Init(DN_POSIXCore *posix); +DN_API void DN_Posix_ThreadSetName(DN_Str8 name); +DN_API DN_POSIXProcSelfStatus DN_Posix_ProcSelfStatus(); +#endif // !defined(DN_OS_POSIX_H) +#else + #error Please define a platform e.g. 'DN_PLATFORM_WIN32' to enable the correct implementation for platform APIs +#endif + +// DN: Single header generator commented out this header => #include "OS/dn_os_tls.h" +#if !defined(DN_OS_TLS_H) +#define DN_OS_TLS_H + +#if defined(_CLANGD) + // 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" +#endif + +// NOTE: DN_OSErrSink +enum DN_OSErrSinkMode +{ + DN_OSErrSinkMode_Nil, // Default behaviour to accumulate errors into the sink + DN_OSErrSinkMode_DebugBreakOnEndAndLog, // Debug break (int3) when error is encountered and the sink is ended by the 'end and log' functions. + DN_OSErrSinkMode_ExitOnError, // When an error is encountered, exit the program with the error code of the error that was caught. +}; + +struct DN_OSErrSinkMsg +{ + DN_I32 error_code; + DN_Str8 msg; + DN_CallSite call_site; + DN_OSErrSinkMsg *next; + DN_OSErrSinkMsg *prev; +}; + +struct DN_OSErrSinkNode +{ + DN_CallSite call_site; // Call site that the node was created + DN_OSErrSinkMode mode; // Controls how the sink behaves when an error is registered onto the sink. + DN_OSErrSinkMsg *msg_sentinel; // List of error messages accumulated for the current scope + DN_U64 arena_pos; // Position to reset the arena when the scope is ended +}; + +struct DN_OSErrSink +{ + DN_Arena * arena; // Dedicated allocator from the thread's local storage + DN_OSErrSinkNode stack[128]; // Each entry contains errors accumulated between a [begin, end] region of the active sink. + DN_USize stack_size; +}; + +enum DN_OSTLSArena +{ + DN_OSTLSArena_Main, // NOTE: Arena for permanent allocations + DN_OSTLSArena_ErrorSink, // NOTE: Arena for logging error information for this thread + + // NOTE: Per-thread scratch arenas (2 to prevent aliasing) + DN_OSTLSArena_TMem0, + DN_OSTLSArena_TMem1, + + DN_OSTLSArena_Count, +}; + +struct DN_OSTLS +{ + DN_B32 init; // Flag to track if TLS has been initialised + DN_U64 thread_id; + DN_CallSite call_site; // Stores call-site information when requested by thread + DN_OSErrSink err_sink; // Error handling state + DN_Arena arenas[DN_OSTLSArena_Count]; // Default arenas that the thread has access to implicitly + DN_Arena * arena_stack[8]; // Active stack of arenas push/popped arenas on into the TLS + DN_USize arena_stack_index; + + DN_Arena * frame_arena; + char name[64]; + DN_U8 name_size; +}; + +// Push the temporary memory arena when retrieved, popped when the arena goes +// out of scope. Pushed arenas are used automatically as the allocator in TLS +// suffixed function. +enum DN_OSTLSPushTMem +{ + DN_OSTLSPushTMem_No, + DN_OSTLSPushTMem_Yes, +}; + +struct DN_OSTLSTMem +{ + DN_OSTLSTMem(DN_OSTLS *context, uint8_t context_index, DN_OSTLSPushTMem push_scratch); + ~DN_OSTLSTMem(); + DN_Arena *arena; + DN_B32 destructed; + DN_OSTLSPushTMem push_arena; + DN_ArenaTempMem temp_mem; +}; + +struct DN_OSTLSInitArgs +{ + DN_U64 reserve; + DN_U64 commit; + DN_U64 err_sink_reserve; + DN_U64 err_sink_commit; +}; + +DN_API void DN_OS_TLSInit (DN_OSTLS *tls, DN_OSTLSInitArgs args); +DN_API void DN_OS_TLSDeinit (DN_OSTLS *tls); +DN_API DN_OSTLS * DN_OS_TLSGet (); +DN_API void DN_OS_TLSSetCurrentThreadTLS (DN_OSTLS *tls); +DN_API DN_Arena * DN_OS_TLSArena (); +DN_API DN_OSTLSTMem DN_OS_TLSGetTMem (void const *conflict_arena, DN_OSTLSPushTMem push_tmp_mem); +DN_API void DN_OS_TLSPushArena (DN_Arena *arena); +DN_API void DN_OS_TLSPopArena (); +DN_API DN_Arena * DN_OS_TLSTopArena (); +DN_API void DN_OS_TLSBeginFrame (DN_Arena *frame_arena); +DN_API DN_Arena * DN_OS_TLSFrameArena (); +#define DN_OS_TLSSaveCallSite do { DN_OS_TLSGet()->call_site = DN_CALL_SITE; } while (0) +#define DN_OS_TLSTMem(...) DN_OS_TLSGetTMem(__VA_ARGS__, DN_OSTLSPushTMem_No) +#define DN_OS_TLSPushTMem(...) DN_OS_TLSGetTMem(__VA_ARGS__, DN_OSTLSPushTMem_Yes) + +DN_API DN_OSErrSink * DN_OS_ErrSinkBegin_ (DN_OSErrSinkMode mode, DN_CallSite call_site); +#define DN_OS_ErrSinkBegin(mode) DN_OS_ErrSinkBegin_(mode, DN_CALL_SITE) +#define DN_OS_ErrSinkBeginDefault() DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil) +DN_API bool DN_OS_ErrSinkHasError (DN_OSErrSink *err); +DN_API DN_OSErrSinkMsg * DN_OS_ErrSinkEnd (DN_Arena *arena, DN_OSErrSink *err); +DN_API DN_Str8 DN_OS_ErrSinkEndStr8 (DN_Arena *arena, DN_OSErrSink *err); +DN_API void DN_OS_ErrSinkEndAndIgnore (DN_OSErrSink *err); +DN_API bool DN_OS_ErrSinkEndAndLogError_ (DN_OSErrSink *err, DN_CallSite call_site, DN_Str8 msg); +DN_API bool DN_OS_ErrSinkEndAndLogErrorFV_ (DN_OSErrSink *err, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API bool DN_OS_ErrSinkEndAndLogErrorF_ (DN_OSErrSink *err, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, ...); +DN_API void DN_OS_ErrSinkEndAndExitIfErrorF_ (DN_OSErrSink *err, DN_CallSite call_site, DN_U32 exit_val, DN_FMT_ATTRIB char const *fmt, ...); +DN_API void DN_OS_ErrSinkEndAndExitIfErrorFV_ (DN_OSErrSink *err, DN_CallSite call_site, DN_U32 exit_val, DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API void DN_OS_ErrSinkAppendFV_ (DN_OSErrSink *err, DN_U32 error_code, DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API void DN_OS_ErrSinkAppendF_ (DN_OSErrSink *err, DN_U32 error_code, DN_FMT_ATTRIB char const *fmt, ...); +#define DN_OS_ErrSinkEndAndLogError(err, err_msg) DN_OS_ErrSinkEndAndLogError_(err, DN_CALL_SITE, err_msg) +#define DN_OS_ErrSinkEndAndLogErrorFV(err, fmt, args) DN_OS_ErrSinkEndAndLogErrorFV_(err, DN_CALL_SITE, fmt, args) +#define DN_OS_ErrSinkEndAndLogErrorF(err, fmt, ...) DN_OS_ErrSinkEndAndLogErrorF_(err, DN_CALL_SITE, fmt, ##__VA_ARGS__) +#define DN_OS_ErrSinkEndAndExitIfErrorFV(err, exit_val, fmt, args) DN_OS_ErrSinkEndAndExitIfErrorFV_(err, DN_CALL_SITE, exit_val, fmt, args) +#define DN_OS_ErrSinkEndAndExitIfErrorF(err, exit_val, fmt, ...) DN_OS_ErrSinkEndAndExitIfErrorF_(err, DN_CALL_SITE, exit_val, fmt, ##__VA_ARGS__) + +#define DN_OS_ErrSinkAppendFV(error, error_code, fmt, args) \ + do { \ + DN_OS_TLSSaveCallSite; \ + DN_OS_ErrSinkAppendFV_(error, error_code, fmt, args); \ + } while (0) + +#define DN_OS_ErrSinkAppendF(error, error_code, fmt, ...) \ + do { \ + DN_OS_TLSSaveCallSite; \ + DN_OS_ErrSinkAppendF_(error, error_code, fmt, ##__VA_ARGS__); \ + } while (0) + +#endif // defined(DN_OS_TLS_H) +// DN: Single header generator commented out this header => #include "OS/dn_os.h" +#if !defined(DN_OS_H) +#define DN_OS_H + +#if defined(_CLANGD) + // 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" +#endif + +#include // operator new + +#if !defined(DN_OS_WIN32) || defined(DN_OS_WIN32_USE_PTHREADS) + #include + #include +#endif + +#if defined(DN_PLATFORM_POSIX) || defined(DN_PLATFORM_EMSCRIPTEN) + #include // errno + #include // O_RDONLY ... etc + #include // ioctl + #include // mmap + #include // getrandom + #include // stat + #include // pid_t + #include // waitpid + #include // clock_gettime, nanosleep + #include // access, gettid, write + + #if !defined(DN_PLATFORM_EMSCRIPTEN) + #include // FICLONE + #include // sendfile + #endif +#endif + +#if defined(DN_PLATFORM_EMSCRIPTEN) + #include // emscripten_fetch (for DN_OSHttpResponse) +#endif + +extern DN_CPUFeatureDecl g_dn_cpu_feature_decl[DN_CPUFeature_Count]; + +// NOTE: DN_OSDate ///////////////////////////////////////////////////////////////////////////////// +struct DN_OSDateTimeStr8 +{ + char date[DN_ArrayCountU("YYYY-MM-SS")]; + DN_U8 date_size; + char hms[DN_ArrayCountU("HH:MM:SS")]; + DN_U8 hms_size; +}; + +struct DN_OSDateTime +{ + DN_U8 day; + DN_U8 month; + DN_U16 year; + DN_U8 hour; + DN_U8 minutes; + DN_U8 seconds; +}; + +struct DN_OSTimer /// Record time between two time-points using the OS's performance counter. +{ + DN_U64 start; + DN_U64 end; +}; + +#if !defined(DN_NO_OS_FILE_API) +// NOTE: DN_OSFile ///////////////////////////////////////////////////////////////////////////////// +enum DN_OSPathInfoType +{ + DN_OSPathInfoType_Unknown, + DN_OSPathInfoType_Directory, + DN_OSPathInfoType_File, +}; + +struct DN_OSPathInfo +{ + bool exists; + DN_OSPathInfoType type; + DN_U64 create_time_in_s; + DN_U64 last_write_time_in_s; + DN_U64 last_access_time_in_s; + DN_U64 size; +}; + +struct DN_OSDirIterator +{ + void *handle; + DN_Str8 file_name; + char buffer[512]; +}; + +// NOTE: R/W Stream API //////////////////////////////////////////////////////////////////////////// +struct DN_OSFileRead +{ + bool success; + DN_USize bytes_read; +}; + +struct DN_OSFile +{ + bool error; + void *handle; +}; + +enum DN_OSFileOpen +{ + DN_OSFileOpen_CreateAlways, // Create file if it does not exist, otherwise, zero out the file and open + DN_OSFileOpen_OpenIfExist, // Open file at path only if it exists + DN_OSFileOpen_OpenAlways, // Open file at path, create file if it does not exist +}; + +typedef DN_U32 DN_OSFileAccess; + +enum DN_OSFileAccess_ +{ + DN_OSFileAccess_Read = 1 << 0, + DN_OSFileAccess_Write = 1 << 1, + DN_OSFileAccess_Execute = 1 << 2, + DN_OSFileAccess_AppendOnly = 1 << 3, // This flag cannot be combined with any other access mode + DN_OSFileAccess_ReadWrite = DN_OSFileAccess_Read | DN_OSFileAccess_Write, + DN_OSFileAccess_All = DN_OSFileAccess_ReadWrite | DN_OSFileAccess_Execute | DN_OSFileAccess_AppendOnly, +}; +#endif // DN_NO_OS_FILE_API + +// NOTE: DN_OSPath //////////////////////////////////////////////////////////////////////////////// +#if !defined(DN_OSPathSeperator) + #if defined(DN_OS_WIN32) + #define DN_OSPathSeperator "\\" + #else + #define DN_OSPathSeperator "/" + #endif + #define DN_OSPathSeperatorString DN_Str8Lit(DN_OSPathSeperator) +#endif + +struct DN_OSPathLink +{ + DN_Str8 string; + DN_OSPathLink *next; + DN_OSPathLink *prev; +}; + +struct DN_OSPath +{ + bool has_prefix_path_separator; + DN_OSPathLink *head; + DN_OSPathLink *tail; + DN_USize string_size; + DN_U16 links_size; +}; + +// NOTE: DN_OSExec ///////////////////////////////////////////////////////////////////////////////// +typedef DN_U32 DN_OSExecFlags; + +enum DN_OSExecFlags_ +{ + DN_OSExecFlags_Nil = 0, + DN_OSExecFlags_SaveStdout = 1 << 0, + DN_OSExecFlags_SaveStderr = 1 << 1, + DN_OSExecFlags_SaveOutput = DN_OSExecFlags_SaveStdout | DN_OSExecFlags_SaveStderr, + DN_OSExecFlags_MergeStderrToStdout = 1 << 2 | DN_OSExecFlags_SaveOutput, +}; + +struct DN_OSExecAsyncHandle +{ + DN_OSExecFlags exec_flags; + DN_U32 os_error_code; + DN_U32 exit_code; + void *process; + void *stdout_read; + void *stdout_write; + void *stderr_read; + void *stderr_write; +}; + +struct DN_OSExecResult +{ + bool finished; + DN_Str8 stdout_text; + DN_Str8 stderr_text; + DN_U32 os_error_code; + DN_U32 exit_code; +}; + +struct DN_OSExecArgs +{ + DN_OSExecFlags flags; + DN_Str8 working_dir; + DN_Slice environment; +}; + +// NOTE: DN_OSSemaphore //////////////////////////////////////////////////////////////////////////// +DN_U32 const DN_OS_SEMAPHORE_INFINITE_TIMEOUT = UINT32_MAX; + +struct DN_OSSemaphore +{ + DN_U64 handle; +}; + +enum DN_OSSemaphoreWaitResult +{ + DN_OSSemaphoreWaitResult_Failed, + DN_OSSemaphoreWaitResult_Success, + DN_OSSemaphoreWaitResult_Timeout, +}; + +struct DN_OSMutex +{ + DN_U64 handle; +}; + +struct DN_OSConditionVariable +{ + DN_U64 handle; +}; + +// NOTE: DN_OSThread +typedef DN_I32(DN_OSThreadFunc)(struct DN_OSThread *); + +struct DN_OSThread +{ + DN_Str8x64 name; + DN_OSTLS tls; + DN_OSTLSInitArgs tls_init_args; + void *handle; + DN_U64 thread_id; + void *user_context; + DN_OSThreadFunc *func; + DN_OSSemaphore init_semaphore; +}; + +// NOTE: DN_OSHttp +enum DN_OSHttpRequestSecure +{ + DN_OSHttpRequestSecure_No, + DN_OSHttpRequestSecure_Yes, +}; + +struct DN_OSHttpResponse +{ + // NOTE: Response data + DN_U32 error_code; + DN_Str8 error_msg; + DN_U16 http_status; + DN_Str8 body; + DN_B32 done; + + // NOTE: Book-keeping + DN_Arena *arena; // Allocates memory for the response + + // NOTE: Async book-keeping + // Synchronous HTTP response uses the TLS scratch arena whereas async + // calls use their own dedicated arena. + DN_Arena tmp_arena; + DN_Arena *tmem_arena; + DN_Str8Builder builder; + DN_OSSemaphore on_complete_semaphore; + + #if defined(DN_PLATFORM_EMSCRIPTEN) + emscripten_fetch_t *em_handle; + #elif defined(DN_PLATFORM_WIN32) + HINTERNET w32_request_session; + HINTERNET w32_request_connection; + HINTERNET w32_request_handle; #endif }; +struct DN_OSCore +{ + DN_CPUReport cpu_report; + DN_OSTLS tls; // Thread local storage state for the main thread. + + // NOTE: Logging + DN_LOGEmitFromTypeFVFunc * log_callback; // Set this pointer to override the logging routine + void * log_user_data; // User pointer passed into 'log_callback' + bool log_to_file; // Output logs to file as well as standard out + DN_OSFile log_file; // TODO(dn): Hmmm, how should we do this... ? + DN_TicketMutex log_file_mutex; // Is locked when instantiating the log_file for the first time + bool log_no_colour; // Disable colours in the logging output + + // NOTE: OS + DN_U32 logical_processor_count; + DN_U32 page_size; + DN_U32 alloc_granularity; + + // NOTE: Memory + // Total OS mem allocs in lifetime of program (e.g. malloc, VirtualAlloc, HeapAlloc ...). This + // only includes allocations routed through the library such as the growing nature of arenas or + // using the memory allocation routines in the library like DN_OS_MemCommit and so forth. + DN_U64 vmem_allocs_total; + DN_U64 vmem_allocs_frame; // Total OS virtual memory allocs since the last 'DN_Core_FrameBegin' was invoked + DN_U64 mem_allocs_total; + DN_U64 mem_allocs_frame; // Total OS heap allocs since the last 'DN_Core_FrameBegin' was invoked + + DN_Arena arena; + void *platform_context; +}; + +struct DN_OSDiskSpace +{ + bool success; + DN_U64 avail; + DN_U64 size; +}; + +DN_API void DN_OS_EmitLogsWithOSPrintFunctions (DN_OSCore *os); +DN_API void DN_OS_DumpThreadContextArenaStat (DN_Str8 file_path); + +DN_API DN_Str8 DN_OS_BytesFromHexPtrArenaFrame (void const *hex, DN_USize hex_count); +DN_API DN_Str8 DN_OS_BytesFromHexStr8ArenaFrame (DN_Str8 hex); +DN_API DN_Str8 DN_OS_HexFromBytesPtrArenaFrame (void const *bytes, DN_USize bytes_count); +DN_API DN_Str8 DN_OS_HexFromBytesPtrArenaTLS (void const *bytes, DN_USize bytes_count); + +DN_API void * DN_OS_MemReserve (DN_USize size, DN_MemCommit commit, DN_MemPage page_flags); +DN_API bool DN_OS_MemCommit (void *ptr, DN_USize size, DN_U32 page_flags); +DN_API void DN_OS_MemDecommit (void *ptr, DN_USize size); +DN_API void DN_OS_MemRelease (void *ptr, DN_USize size); +DN_API int DN_OS_MemProtect (void *ptr, DN_USize size, DN_U32 page_flags); + +DN_API void * DN_OS_MemAlloc (DN_USize size, DN_ZMem z_mem); +DN_API void DN_OS_MemDealloc (void *ptr); + +DN_API DN_OSDateTime DN_OS_DateLocalTimeNow (); +DN_API DN_OSDateTimeStr8 DN_OS_DateLocalTimeStr8Now (char date_separator = '-', char hms_separator = ':'); +DN_API DN_OSDateTimeStr8 DN_OS_DateLocalTimeStr8 (DN_OSDateTime time, char date_separator = '-', char hms_separator = ':'); +DN_API DN_U64 DN_OS_DateUnixTimeNs (); +#define DN_OS_DateUnixTimeUs() (DN_OS_DateUnixTimeNs() / 1000) +#define DN_OS_DateUnixTimeMs() (DN_OS_DateUnixTimeNs() / (1000 * 1000)) +#define DN_OS_DateUnixTimeS() (DN_OS_DateUnixTimeNs() / (1000 * 1000 * 1000)) +DN_API DN_OSDateTime DN_OS_DateUnixTimeSToDate (DN_U64 time); +DN_API DN_U64 DN_OS_DateLocalToUnixTimeS (DN_OSDateTime date); +DN_API DN_U64 DN_OS_DateToUnixTimeS (DN_OSDateTime date); +DN_API bool DN_OS_DateIsValid (DN_OSDateTime date); + +DN_API void DN_OS_GenBytesSecure (void *buffer, DN_U32 size); +DN_API bool DN_OS_SetEnvVar (DN_Str8 name, DN_Str8 value); +DN_API DN_OSDiskSpace DN_OS_DiskSpace (DN_Str8 path); +DN_API DN_Str8 DN_OS_EXEPath (DN_Arena *arena); +DN_API DN_Str8 DN_OS_EXEDir (DN_Arena *arena); +#define DN_OS_EXEDirFromTLS() DN_OS_EXEDir(DN_OS_TLSTopArena()) +DN_API void DN_OS_SleepMs (DN_UInt milliseconds); + +DN_API DN_U64 DN_OS_PerfCounterNow (); +DN_API DN_U64 DN_OS_PerfCounterFrequency (); +DN_API DN_F64 DN_OS_PerfCounterS (DN_U64 begin, uint64_t end); +DN_API DN_F64 DN_OS_PerfCounterMs (DN_U64 begin, uint64_t end); +DN_API DN_F64 DN_OS_PerfCounterUs (DN_U64 begin, uint64_t end); +DN_API DN_F64 DN_OS_PerfCounterNs (DN_U64 begin, uint64_t end); +DN_API DN_OSTimer DN_OS_TimerBegin (); +DN_API void DN_OS_TimerEnd (DN_OSTimer *timer); +DN_API DN_F64 DN_OS_TimerS (DN_OSTimer timer); +DN_API DN_F64 DN_OS_TimerMs (DN_OSTimer timer); +DN_API DN_F64 DN_OS_TimerUs (DN_OSTimer timer); +DN_API DN_F64 DN_OS_TimerNs (DN_OSTimer timer); +DN_API DN_U64 DN_OS_EstimateTSCPerSecond (uint64_t duration_ms_to_gauge_tsc_frequency); + +DN_API bool DN_OS_FileCopy (DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *err); +DN_API bool DN_OS_FileMove (DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSink *err); + +DN_API DN_OSFile DN_OS_FileOpen (DN_Str8 path, DN_OSFileOpen open_mode, DN_OSFileAccess access, DN_OSErrSink *err); +DN_API DN_OSFileRead DN_OS_FileRead (DN_OSFile *file, void *buffer, DN_USize size, DN_OSErrSink *err); +DN_API bool DN_OS_FileWritePtr (DN_OSFile *file, void const *data, DN_USize size, DN_OSErrSink *err); +DN_API bool DN_OS_FileWrite (DN_OSFile *file, DN_Str8 buffer, DN_OSErrSink *err); +DN_API bool DN_OS_FileWriteFV (DN_OSFile *file, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API bool DN_OS_FileWriteF (DN_OSFile *file, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, ...); +DN_API bool DN_OS_FileFlush (DN_OSFile *file, DN_OSErrSink *err); +DN_API void DN_OS_FileClose (DN_OSFile *file); + +DN_API DN_Str8 DN_OS_FileReadAll (DN_Allocator alloc_type, void *allocator, DN_Str8 path, DN_OSErrSink *err); +DN_API DN_Str8 DN_OS_FileReadAllArena (DN_Arena *arena, DN_Str8 path, DN_OSErrSink *err); +DN_API DN_Str8 DN_OS_FileReadAllPool (DN_Pool *pool, DN_Str8 path, DN_OSErrSink *err); +DN_API DN_Str8 DN_OS_FileReadAllTLS (DN_Str8 path, DN_OSErrSink *err); +DN_API bool DN_OS_FileWriteAll (DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *err); +DN_API bool DN_OS_FileWriteAllFV (DN_Str8 path, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API bool DN_OS_FileWriteAllF (DN_Str8 path, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, ...); +DN_API bool DN_OS_FileWriteAllSafe (DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *err); +DN_API bool DN_OS_FileWriteAllSafeFV (DN_Str8 path, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API bool DN_OS_FileWriteAllSafeF (DN_Str8 path, DN_OSErrSink *err, DN_FMT_ATTRIB char const *fmt, ...); + +DN_API DN_OSPathInfo DN_OS_PathInfo (DN_Str8 path); +DN_API bool DN_OS_PathIsOlderThan (DN_Str8 file, DN_Str8 check_against); +DN_API bool DN_OS_PathDelete (DN_Str8 path); +DN_API bool DN_OS_PathIsFile (DN_Str8 path); +DN_API bool DN_OS_PathIsDir (DN_Str8 path); +DN_API bool DN_OS_PathMakeDir (DN_Str8 path); +DN_API bool DN_OS_PathIterateDir (DN_Str8 path, DN_OSDirIterator *it); + +DN_API bool DN_OS_PathAddRef (DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path); +DN_API bool DN_OS_PathAddRefTLS (DN_OSPath *fs_path, DN_Str8 path); +DN_API bool DN_OS_PathAddRefFrame (DN_OSPath *fs_path, DN_Str8 path); +DN_API bool DN_OS_PathAdd (DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path); +#define DN_OS_PathAddFromTLS(...) DN_OS_PathAdd(DN_OS_TLSTopArena(), ##__VA_ARGS__) +#define DN_OS_PathAddFromFrame(...) DN_OS_PathAdd(DN_OS_TLSFrameArena(), ##__VA_ARGS__) +DN_API bool DN_OS_PathAddF (DN_Arena *arena, DN_OSPath *fs_path, DN_FMT_ATTRIB char const *fmt, ...); +#define DN_OS_PathAddFFromTLS(...) DN_OS_PathAddF(DN_OS_TLSTopArena(), ##__VA_ARGS__) +#define DN_OS_PathAddFFromFrame(...) DN_OS_PathAddF(DN_OS_TLSFrameArena(), ##__VA_ARGS__) +DN_API bool DN_OS_PathPop (DN_OSPath *fs_path); +DN_API DN_Str8 DN_OS_PathBuildWithSeparator (DN_Arena *arena, DN_OSPath const *fs_path, DN_Str8 path_separator); +#define DN_OS_PathBuildWithSeperatorFromTLS(...) DN_OS_PathBuildWithSeperator(DN_OS_TLSTopArena(), ##__VA_ARGS__) +#define DN_OS_PathBuildWithSeperatorFromFrame(...) DN_OS_PathBuildWithSeperator(DN_OS_TLSFrameArena(), ##__VA_ARGS__) +DN_API DN_Str8 DN_OS_PathTo (DN_Arena *arena, DN_Str8 path, DN_Str8 path_separtor); +#define DN_OS_PathToFromTLS(...) DN_OS_PathTo(DN_OS_TLSTopArena(), ##__VA_ARGS__) +#define DN_OS_PathToFromFrame(...) DN_OS_PathTo(DN_OS_TLSFrameArena(), ##__VA_ARGS__) +DN_API DN_Str8 DN_OS_PathToF (DN_Arena *arena, DN_Str8 path_separator, DN_FMT_ATTRIB char const *fmt, ...); +#define DN_OS_PathToFFromTLS(...) DN_OS_PathToF(DN_OS_TLSTopArena(), ##__VA_ARGS__) +#define DN_OS_PathToFFromFrame(...) DN_OS_PathToF(DN_OS_TLSFrameArena(), ##__VA_ARGS__) +DN_API DN_Str8 DN_OS_Path (DN_Arena *arena, DN_Str8 path); +#define DN_OS_PathFromTLS(...) DN_OS_Path(DN_OS_TLSTopArena(), ##__VA_ARGS__) +#define DN_OS_PathFromFrame(...) DN_OS_Path(DN_OS_TLSFrameArena(), ##__VA_ARGS__) +DN_API DN_Str8 DN_OS_PathF (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...); +#define DN_OS_PathFFromTLS(...) DN_OS_PathF(DN_OS_TLSTopArena(), ##__VA_ARGS__) +#define DN_OS_PathFFromFrame(...) DN_OS_PathF(DN_OS_TLSFrameArena(), ##__VA_ARGS__) + +#define DN_OS_PathBuildFwdSlash(allocator, fs_path) DN_OS_PathBuildWithSeparator(allocator, fs_path, DN_Str8Lit("/")) +#define DN_OS_PathBuildBackSlash(allocator, fs_path) DN_OS_PathBuildWithSeparator(allocator, fs_path, DN_Str8Lit("\\")) +#define DN_OS_PathBuild(allocator, fs_path) DN_OS_PathBuildWithSeparator(allocator, fs_path, DN_OSPathSeparatorString) + +DN_API void DN_OS_Exit (int32_t exit_code); +DN_API DN_OSExecResult DN_OS_ExecPump (DN_OSExecAsyncHandle handle, char *stdout_buffer, size_t *stdout_size, char *stderr_buffer, size_t *stderr_size, DN_U32 timeout_ms, DN_OSErrSink *err); +DN_API DN_OSExecResult DN_OS_ExecWait (DN_OSExecAsyncHandle handle, DN_Arena *arena, DN_OSErrSink *err); +DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync (DN_Slice cmd_line, DN_OSExecArgs *args, DN_OSErrSink *err); +DN_API DN_OSExecResult DN_OS_Exec (DN_Slice cmd_line, DN_OSExecArgs *args, DN_Arena *arena, DN_OSErrSink *err); +DN_API DN_OSExecResult DN_OS_ExecOrAbort (DN_Slice cmd_line, DN_OSExecArgs *args, DN_Arena *arena); +#define DN_OS_ExecOrAbortFromTLS (...) DN_OS_ExecOrAbort(__VA_ARGS__, DN_OS_TLSTopArena()) + +DN_API DN_OSSemaphore DN_OS_SemaphoreInit (DN_U32 initial_count); +DN_API bool DN_OS_SemaphoreIsValid (DN_OSSemaphore *semaphore); +DN_API void DN_OS_SemaphoreDeinit (DN_OSSemaphore *semaphore); +DN_API void DN_OS_SemaphoreIncrement (DN_OSSemaphore *semaphore, DN_U32 amount); +DN_API DN_OSSemaphoreWaitResult DN_OS_SemaphoreWait (DN_OSSemaphore *semaphore, DN_U32 timeout_ms); + +DN_API DN_OSMutex DN_OS_MutexInit (); +DN_API void DN_OS_MutexDeinit (DN_OSMutex *mutex); +DN_API void DN_OS_MutexLock (DN_OSMutex *mutex); +DN_API void DN_OS_MutexUnlock (DN_OSMutex *mutex); +#define DN_OS_MutexScope(mutex) DN_DeferLoop(DN_OS_MutexLock(mutex), DN_OS_MutexUnlock(mutex)) + +DN_API DN_OSConditionVariable DN_OS_ConditionVariableInit (); +DN_API void DN_OS_ConditionVariableDeinit (DN_OSConditionVariable *cv); +DN_API bool DN_OS_ConditionVariableWait (DN_OSConditionVariable *cv, DN_OSMutex *mutex, DN_U64 sleep_ms); +DN_API bool DN_OS_ConditionVariableWaitUntil (DN_OSConditionVariable *cv, DN_OSMutex *mutex, DN_U64 end_ts_ms); +DN_API void DN_OS_ConditionVariableSignal (DN_OSConditionVariable *cv); +DN_API void DN_OS_ConditionVariableBroadcast (DN_OSConditionVariable *cv); + +DN_API bool DN_OS_ThreadInit (DN_OSThread *thread, DN_OSThreadFunc *func, void *user_context); +DN_API void DN_OS_ThreadDeinit (DN_OSThread *thread); +DN_API DN_U32 DN_OS_ThreadID (); +DN_API void DN_OS_ThreadSetName (DN_Str8 name); + +DN_API void DN_OS_HttpRequestAsync (DN_OSHttpResponse *response, DN_Arena *arena, DN_Str8 host, DN_Str8 path, DN_OSHttpRequestSecure secure, DN_Str8 method, DN_Str8 body, DN_Str8 headers); +DN_API void DN_OS_HttpRequestWait (DN_OSHttpResponse *response); +DN_API void DN_OS_HttpRequestFree (DN_OSHttpResponse *response); +DN_API DN_OSHttpResponse DN_OS_HttpRequest (DN_Arena *arena, DN_Str8 host, DN_Str8 path, DN_OSHttpRequestSecure secure, DN_Str8 method, DN_Str8 body, DN_Str8 headers); +#endif // !defined(DN_OS_H) +// DN: Single header generator commented out this header => #include "OS/dn_os_allocator.h" +#if !defined(DN_OS_ALLOCATOR_H) +#define DN_OS_ALLOCATOR_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +DN_API DN_Arena DN_ArenaFromHeap(DN_U64 size, DN_ArenaFlags flags); +DN_API DN_Arena DN_ArenaFromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags); + +#endif // !defined(DN_OS_ALLOCATOR_H) +// DN: Single header generator commented out this header => #include "OS/dn_os_containers.h" +#if !defined(DN_OS_CONTAINERS_H) +#define DN_OS_CONTAINERS_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +// NOTE: DN_VArray +// TODO(doyle): Add an API for shrinking the array by decomitting pages back to the OS. +template struct DN_VArray +{ + T *data; // Pointer to the start of the array items in the block of memory + DN_USize size; // Number of items currently in the array + DN_USize max; // Maximum number of items this array can store + DN_USize commit; // Bytes committed + + T *begin() { return data; } + T *end () { return data + size; } + T const *begin() const { return data; } + T const *end () const { return data + size; } +}; + +template DN_VArray DN_VArray_InitByteSize (DN_USize byte_size); +template DN_VArray DN_VArray_Init (DN_USize max); +template DN_VArray DN_VArray_InitSlice (DN_Slice slice, DN_USize max); +template DN_VArray DN_VArray_InitCArray (T const (&items)[N], DN_USize max); +template void DN_VArray_Deinit (DN_VArray *array); +template bool DN_VArray_IsValid (DN_VArray const *array); +template DN_Slice DN_VArray_Slice (DN_VArray const *array); +template bool DN_VArray_Reserve (DN_VArray *array, DN_USize count); +template T * DN_VArray_AddArray (DN_VArray *array, T const *items, DN_USize count); +template T * DN_VArray_AddCArray (DN_VArray *array, T const (&items)[N]); +template T * DN_VArray_Add (DN_VArray *array, T const &item); +#define DN_VArray_AddArrayAssert(...) DN_HardAssert(DN_VArray_AddArray(__VA_ARGS__)) +#define DN_VArray_AddCArrayAssert(...) DN_HardAssert(DN_VArray_AddCArray(__VA_ARGS__)) +#define DN_VArray_AddAssert(...) DN_HardAssert(DN_VArray_Add(__VA_ARGS__)) +template T * DN_VArray_MakeArray (DN_VArray *array, DN_USize count, DN_ZMem z_mem); +template T * DN_VArray_Make (DN_VArray *array, DN_ZMem z_mem); +#define DN_VArray_MakeArrayAssert(...) DN_HardAssert(DN_VArray_MakeArray(__VA_ARGS__)) +#define DN_VArray_MakeAssert(...) DN_HardAssert(DN_VArray_Make(__VA_ARGS__)) +template T * DN_VArray_InsertArray (DN_VArray *array, DN_USize index, T const *items, DN_USize count); +template T * DN_VArray_InsertCArray (DN_VArray *array, DN_USize index, T const (&items)[N]); +template T * DN_VArray_Insert (DN_VArray *array, DN_USize index, T const &item); +#define DN_VArray_InsertArrayAssert(...) DN_HardAssert(DN_VArray_InsertArray(__VA_ARGS__)) +#define DN_VArray_InsertCArrayAssert(...) DN_HardAssert(DN_VArray_InsertCArray(__VA_ARGS__)) +#define DN_VArray_InsertAssert(...) DN_HardAssert(DN_VArray_Insert(__VA_ARGS__)) +template T DN_VArray_PopFront (DN_VArray *array, DN_USize count); +template T DN_VArray_PopBack (DN_VArray *array, DN_USize count); +template DN_ArrayEraseResult DN_VArray_EraseRange (DN_VArray *array, DN_USize begin_index, DN_ISize count, DN_ArrayErase erase); +template void DN_VArray_Clear (DN_VArray *array, DN_ZMem z_mem); +#endif // !defined(DN_OS_CONTAINERS_H) +// DN: Single header generator commented out this header => #include "OS/dn_os_print.h" +#if !defined(DN_OS_PRINT_H) +#define DN_OS_PRINT_H + +enum DN_OSPrintDest +{ + DN_OSPrintDest_Out, + DN_OSPrintDest_Err, +}; + +// NOTE: Print Macros +#define DN_OS_PrintOut(string) DN_OS_Print(DN_OSPrintDest_Out, string) +#define DN_OS_PrintOutF(fmt, ...) DN_OS_PrintF(DN_OSPrintDest_Out, fmt, ##__VA_ARGS__) +#define DN_OS_PrintOutFV(fmt, args) DN_OS_PrintFV(DN_OSPrintDest_Out, fmt, args) + +#define DN_OS_PrintOutStyle(style, string) DN_OS_PrintStyle(DN_OSPrintDest_Out, style, string) +#define DN_OS_PrintOutFStyle(style, fmt, ...) DN_OS_PrintFStyle(DN_OSPrintDest_Out, style, fmt, ##__VA_ARGS__) +#define DN_OS_PrintOutFVStyle(style, fmt, args, ...) DN_OS_PrintFVStyle(DN_OSPrintDest_Out, style, fmt, args) + +#define DN_OS_PrintOutLn(string) DN_OS_PrintLn(DN_OSPrintDest_Out, string) +#define DN_OS_PrintOutLnF(fmt, ...) DN_OS_PrintLnF(DN_OSPrintDest_Out, fmt, ##__VA_ARGS__) +#define DN_OS_PrintOutLnFV(fmt, args) DN_OS_PrintLnFV(DN_OSPrintDest_Out, fmt, args) + +#define DN_OS_PrintOutLnStyle(style, string) DN_OS_PrintLnStyle(DN_OSPrintDest_Out, style, string); +#define DN_OS_PrintOutLnFStyle(style, fmt, ...) DN_OS_PrintLnFStyle(DN_OSPrintDest_Out, style, fmt, ##__VA_ARGS__) +#define DN_OS_PrintOutLnFVStyle(style, fmt, args) DN_OS_PrintLnFVStyle(DN_OSPrintDest_Out, style, fmt, args); + +#define DN_OS_PrintErr(string) DN_OS_Print(DN_OSPrintDest_Err, string) +#define DN_OS_PrintErrF(fmt, ...) DN_OS_PrintF(DN_OSPrintDest_Err, fmt, ##__VA_ARGS__) +#define DN_OS_PrintErrFV(fmt, args) DN_OS_PrintFV(DN_OSPrintDest_Err, fmt, args) + +#define DN_OS_PrintErrStyle(style, string) DN_OS_PrintStyle(DN_OSPrintDest_Err, style, string) +#define DN_OS_PrintErrFStyle(style, fmt, ...) DN_OS_PrintFStyle(DN_OSPrintDest_Err, style, fmt, ##__VA_ARGS__) +#define DN_OS_PrintErrFVStyle(style, fmt, args, ...) DN_OS_PrintFVStyle(DN_OSPrintDest_Err, style, fmt, args) + +#define DN_OS_PrintErrLn(string) DN_OS_PrintLn(DN_OSPrintDest_Err, string) +#define DN_OS_PrintErrLnF(fmt, ...) DN_OS_PrintLnF(DN_OSPrintDest_Err, fmt, ##__VA_ARGS__) +#define DN_OS_PrintErrLnFV(fmt, args) DN_OS_PrintLnFV(DN_OSPrintDest_Err, fmt, args) + +#define DN_OS_PrintErrLnStyle(style, string) DN_OS_PrintLnStyle(DN_OSPrintDest_Err, style, string); +#define DN_OS_PrintErrLnFStyle(style, fmt, ...) DN_OS_PrintLnFStyle(DN_OSPrintDest_Err, style, fmt, ##__VA_ARGS__) +#define DN_OS_PrintErrLnFVStyle(style, fmt, args) DN_OS_PrintLnFVStyle(DN_OSPrintDest_Err, style, fmt, args); + +// NOTE: Print +DN_API void DN_OS_Print (DN_OSPrintDest dest, DN_Str8 string); +DN_API void DN_OS_PrintF (DN_OSPrintDest dest, DN_FMT_ATTRIB char const *fmt, ...); +DN_API void DN_OS_PrintFV (DN_OSPrintDest dest, DN_FMT_ATTRIB char const *fmt, va_list args); + +DN_API void DN_OS_PrintStyle (DN_OSPrintDest dest, DN_LOGStyle style, DN_Str8 string); +DN_API void DN_OS_PrintFStyle (DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_ATTRIB char const *fmt, ...); +DN_API void DN_OS_PrintFVStyle (DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_ATTRIB char const *fmt, va_list args); + +DN_API void DN_OS_PrintLn (DN_OSPrintDest dest, DN_Str8 string); +DN_API void DN_OS_PrintLnF (DN_OSPrintDest dest, DN_FMT_ATTRIB char const *fmt, ...); +DN_API void DN_OS_PrintLnFV (DN_OSPrintDest dest, DN_FMT_ATTRIB char const *fmt, va_list args); + +DN_API void DN_OS_PrintLnStyle (DN_OSPrintDest dest, DN_LOGStyle style, DN_Str8 string); +DN_API void DN_OS_PrintLnFStyle (DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_ATTRIB char const *fmt, ...); +DN_API void DN_OS_PrintLnFVStyle (DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_ATTRIB char const *fmt, va_list args); +#endif // !defined(DN_OS_PRINT_H) +// DN: Single header generator commented out this header => #include "OS/dn_os_string.h" +#if !defined(DN_OS_STRING_H) +#define DN_OS_STRING_H + +#if defined(_CLANGD) + // 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" +#endif + +// NOTE: DN_Str8 + +DN_API DN_Str8 DN_Str8FromFmtVArenaFrame (DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API DN_Str8 DN_Str8FromFmtArenaFrame (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8 DN_Str8FromArenaFrame (DN_USize size, DN_ZMem z_mem); +DN_API DN_Str8 DN_Str8FromHeapF (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8 DN_Str8FromHeap (DN_USize size, DN_ZMem z_mem); +DN_API DN_Str8 DN_Str8FromTLSFV (DN_FMT_ATTRIB char const *fmt, va_list args); +DN_API DN_Str8 DN_Str8FromTLSF (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8 DN_Str8FromTLS (DN_USize size, DN_ZMem z_mem); +DN_API DN_Str8 DN_Str8FromStr8Frame (DN_Str8 string); +DN_API DN_Str8 DN_Str8FromStr8TLS (DN_Str8 string); + +DN_API DN_Str8SplitResult DN_Str8SplitFromFrame (DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode); +DN_API DN_Str8SplitResult DN_Str8SplitFromTLS (DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode); + +DN_API DN_Str8 DN_Str8SegmentFromFrame (DN_Str8 src, DN_USize segment_size, char segment_char); +DN_API DN_Str8 DN_Str8SegmentFromTLS (DN_Str8 src, DN_USize segment_size, char segment_char); + +DN_API DN_Str8 DN_Str8ReverseSegmentFromFrame (DN_Str8 src, DN_USize segment_size, char segment_char); +DN_API DN_Str8 DN_Str8ReverseSegmentFromTLS (DN_Str8 src, DN_USize segment_size, char segment_char); + +DN_API DN_Str8 DN_Str8AppendFFromFrame (DN_Str8 string, char const *fmt, ...); +DN_API DN_Str8 DN_Str8AppendFFromTLS (DN_Str8 string, char const *fmt, ...); + +DN_API DN_Str8 DN_Str8FillFFromFrame (DN_Str8 string, char const *fmt, ...); +DN_API DN_Str8 DN_Str8FillFFromTLS (DN_Str8 string, char const *fmt, ...); + +DN_API DN_Str8TruncateResult DN_Str8TruncateMiddleArenaFrame (DN_Str8 str8, uint32_t side_size, DN_Str8 truncator); +DN_API DN_Str8TruncateResult DN_Str8TruncateMiddleArenaTLS (DN_Str8 str8, uint32_t side_size, DN_Str8 truncator); + +DN_API DN_Str8 DN_Str8PadNewLines (DN_Arena *arena, DN_Str8 src, DN_Str8 pad); +DN_API DN_Str8 DN_Str8PadNewLinesFromFrame (DN_Str8 src, DN_Str8 pad); +DN_API DN_Str8 DN_Str8PadNewLinesFromTLS (DN_Str8 src, DN_Str8 pad); + +DN_API DN_Str8 DN_Str8UpperFromFrame (DN_Str8 string); +DN_API DN_Str8 DN_Str8UpperFromTLS (DN_Str8 string); + +DN_API DN_Str8 DN_Str8LowerFromFrame (DN_Str8 string); +DN_API DN_Str8 DN_Str8LowerFromTLS (DN_Str8 string); + +DN_API DN_Str8 DN_Str8Replace (DN_Str8 string, DN_Str8 find, DN_Str8 replace, DN_USize start_index, DN_Arena *arena, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive); +DN_API DN_Str8 DN_Str8ReplaceInsensitive (DN_Str8 string, DN_Str8 find, DN_Str8 replace, DN_USize start_index, DN_Arena *arena); + +// NOTE: DN_Str8Builder //////////////////////////////////////////////////////////////////////////// + +DN_API DN_Str8Builder DN_Str8BuilderFromArena () { return DN_Str8BuilderFromArena(DN_OS_TLSGet()->frame_arena); } +DN_API DN_Str8Builder DN_Str8BuilderFromTLS () { return DN_Str8BuilderFromArena(DN_OS_TLSTopArena()); } + +DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrRefFrame (DN_Str8 const *strings, DN_USize size) { return DN_Str8BuilderFromStr8PtrRef(DN_OS_TLSGet()->frame_arena, strings, size); } +DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrRefTLS (DN_Str8 const *strings, DN_USize size) { return DN_Str8BuilderFromStr8PtrRef(DN_OS_TLSTopArena(), strings, size); } +DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrCopyFrame (DN_Str8 const *strings, DN_USize size) { return DN_Str8BuilderFromStr8PtrCopy(DN_OS_TLSGet()->frame_arena, strings, size); } +DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrCopyTLS (DN_Str8 const *strings, DN_USize size) { return DN_Str8BuilderFromStr8PtrCopy(DN_OS_TLSTopArena(), strings, size); } + +DN_API DN_Str8Builder DN_Str8BuilderFromBuilderFrame (DN_Str8Builder const *builder) { return DN_Str8BuilderFromBuilder(DN_OS_TLSGet()->frame_arena, builder); } +DN_API DN_Str8Builder DN_Str8BuilderFromBuilderTLS (DN_Str8Builder const *builder) { return DN_Str8BuilderFromBuilder(DN_OS_TLSTopArena(), builder); } + +DN_API DN_Str8 DN_Str8BuilderBuildFromFrame (DN_Str8Builder const *builder) { return DN_Str8BuilderBuild(builder, DN_OS_TLSGet()->frame_arena); } +DN_API DN_Str8 DN_Str8BuilderBuildFromHeap (DN_Str8Builder const *builder, DN_Arena *arena); +DN_API DN_Str8 DN_Str8BuilderBuildFromTLS (DN_Str8Builder const *builder) { return DN_Str8BuilderBuild(builder, DN_OS_TLSTopArena()); } + +DN_API DN_Str8 DN_Str8BuilderBuildDelimitedFromFrame(DN_Str8Builder const *builder, DN_Str8 delimiter) { return DN_Str8BuilderBuildDelimited(builder, delimiter, DN_OS_TLSGet()->frame_arena); } +DN_API DN_Str8 DN_Str8BuilderBuildDelimitedFromTLS (DN_Str8Builder const *builder, DN_Str8 delimiter) { return DN_Str8BuilderBuildDelimited(builder, delimiter, DN_OS_TLSTopArena()); } + +DN_API DN_Slice DN_Str8BuilderBuildSliceFromFrame (DN_Str8Builder const *builder) { return DN_Str8BuilderBuildSlice(builder, DN_OS_TLSGet()->frame_arena); } +DN_API DN_Slice DN_Str8BuilderBuildSliceFromTLS (DN_Str8Builder const *builder) { return DN_Str8BuilderBuildSlice(builder, DN_OS_TLSTopArena()); } + +#endif // !defined(DN_OS_STRING_H) + +#endif // DN_OS_INC_H +#endif + struct DN_InitArgs { DN_U64 os_tls_reserve; @@ -6336,6 +15413,16 @@ enum DN_InitFlags_ DN_InitFlags_LogAllFeatures = DN_InitFlags_LogLibFeatures | DN_InitFlags_LogCPUFeatures, }; +struct DN_Core +{ + DN_InitFlags init_flags; + DN_USize mem_allocs_frame; + DN_LeakTracker leak; + #if defined(DN_OS_H) + DN_OSCore os; + #endif +}; + extern DN_Core *g_dn_; DN_API void DN_Init(DN_Core *dn, DN_InitFlags flags, DN_InitArgs *args); @@ -6345,7 +15432,9 @@ DN_API void DN_BeginFrame(); #if !defined(DN_MATH_H) #define DN_MATH_H -// DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif DN_MSVC_WARNING_PUSH DN_MSVC_WARNING_DISABLE(4201) // warning C4201: nonstandard extension used: nameless struct/union @@ -6717,8 +15806,10 @@ DN_API DN_F32 DN_Lerp_F32 (DN_F32 a, DN_F #if !defined(DN_ASYNC_H) #define DN_ASYNC_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" +#if defined(_CLANGD) + // 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" +#endif enum DN_ASYNCPriority { @@ -6771,6 +15862,10 @@ DN_API void DN_ASYNC_WaitTask (DN_OSSemaphore *sem, DN_U32 timeout_ms); #if !defined(DN_BIN_PACK_H) #define DN_BIN_PACK_H +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + #if !defined(DN_BASE_INC_H) #error dn_base_inc.h must be included before this #endif @@ -6814,6 +15909,10 @@ DN_API DN_Str8 DN_BinPack_Build (DN_BinPack const #if !defined(DN_CSV_H) #define DN_CSV_H +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + enum DN_CSVSerialise { DN_CSVSerialise_Read, @@ -6840,6 +15939,10 @@ struct DN_CSVPack #if !defined(DN_HASH_H) #define DN_HASH_H +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + /* //////////////////////////////////////////////////////////////////////////////////////////////////// // @@ -6885,6 +15988,385 @@ DN_API DN_MurmurHash3 DN_MurmurHash3_x64U128 (void const *key, int len, uint #if !defined(DN_HELPERS_H) #define DN_HELPERS_H +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" + // DN: Single header generator commented out this header => #include "dn_math.h" +#if !defined(DN_MATH_H) +#define DN_MATH_H + +#if defined(_CLANGD) + // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +#endif + +DN_MSVC_WARNING_PUSH +DN_MSVC_WARNING_DISABLE(4201) // warning C4201: nonstandard extension used: nameless struct/union +union DN_V2I32 +{ + struct { DN_I32 x, y; }; + struct { DN_I32 w, h; }; + DN_I32 data[2]; +}; + +union DN_V2U16 +{ + struct { DN_U16 x, y; }; + struct { DN_U16 w, h; }; + DN_U16 data[2]; +}; + +union DN_V2U32 +{ + struct { DN_U32 x, y; }; + struct { DN_U32 w, h; }; + DN_U32 data[2]; +}; + +union DN_V2F32 +{ + struct { DN_F32 x, y; }; + struct { DN_F32 w, h; }; + DN_F32 data[2]; +}; + +union DN_V3F32 +{ + struct { DN_F32 x, y, z; }; + struct { DN_F32 r, g, b; }; + DN_F32 data[3]; +}; + + +union DN_V4F32 +{ + struct { DN_F32 x, y, z, w; }; + struct { DN_F32 r, g, b, a; }; + #if !defined(DN_NO_V3) + DN_V3F32 rgb; + DN_V3F32 xyz; + #endif + DN_F32 data[4]; +}; +DN_MSVC_WARNING_POP + +struct DN_M4 +{ + DN_F32 columns[4][4]; // Column major matrix +}; + +union DN_M2x3 +{ + DN_F32 e[6]; + DN_F32 row[2][3]; +}; + +struct DN_Rect +{ + DN_V2F32 pos, size; +}; + +struct DN_RectMinMax +{ + DN_V2F32 min, max; +}; + +enum DN_RectCutClip +{ + DN_RectCutClip_No, + DN_RectCutClip_Yes, +}; + +enum DN_RectCutSide +{ + DN_RectCutSide_Left, + DN_RectCutSide_Right, + DN_RectCutSide_Top, + DN_RectCutSide_Bottom, +}; + +struct DN_RectCut +{ + DN_Rect* rect; + DN_RectCutSide side; +}; + +struct DN_RaycastLineIntersectV2Result +{ + bool hit; // True if there was an intersection, false if the lines are parallel + DN_F32 t_a; // Distance along `dir_a` that the intersection occurred, e.g. `origin_a + (dir_a * t_a)` + DN_F32 t_b; // Distance along `dir_b` that the intersection occurred, e.g. `origin_b + (dir_b * t_b)` +}; + +#define DN_V2I32_Zero DN_Literal(DN_V2I32){{(int32_t)(0), (int32_t)(0)}} +#define DN_V2I32_One DN_Literal(DN_V2I32){{(int32_t)(1), (int32_t)(1)}} +#define DN_V2I32_From1N(x) DN_Literal(DN_V2I32){{(int32_t)(x), (int32_t)(x)}} +#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); +DN_API bool operator< (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API bool operator> (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API DN_V2I32 operator- (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API DN_V2I32 operator- (DN_V2I32 lhs); +DN_API DN_V2I32 operator+ (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API DN_V2I32 operator* (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API DN_V2I32 operator* (DN_V2I32 lhs, DN_F32 rhs); +DN_API DN_V2I32 operator* (DN_V2I32 lhs, int32_t rhs); +DN_API DN_V2I32 operator/ (DN_V2I32 lhs, DN_V2I32 rhs); +DN_API DN_V2I32 operator/ (DN_V2I32 lhs, DN_F32 rhs); +DN_API DN_V2I32 operator/ (DN_V2I32 lhs, int32_t rhs); +DN_API DN_V2I32 & operator*= (DN_V2I32& lhs, DN_V2I32 rhs); +DN_API DN_V2I32 & operator*= (DN_V2I32& lhs, DN_F32 rhs); +DN_API DN_V2I32 & operator*= (DN_V2I32& lhs, int32_t rhs); +DN_API DN_V2I32 & operator/= (DN_V2I32& lhs, DN_V2I32 rhs); +DN_API DN_V2I32 & operator/= (DN_V2I32& lhs, DN_F32 rhs); +DN_API DN_V2I32 & operator/= (DN_V2I32& lhs, int32_t rhs); +DN_API DN_V2I32 & operator-= (DN_V2I32& lhs, DN_V2I32 rhs); +DN_API DN_V2I32 & operator+= (DN_V2I32& lhs, DN_V2I32 rhs); + +DN_API DN_V2I32 DN_V2I32_Min (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); + +#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_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)}} + +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); +DN_API bool operator< (DN_V2U16 lhs, DN_V2U16 rhs); +DN_API bool 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); +DN_API DN_V2U16 operator* (DN_V2U16 lhs, DN_F32 rhs); +DN_API DN_V2U16 operator* (DN_V2U16 lhs, int32_t rhs); +DN_API DN_V2U16 operator/ (DN_V2U16 lhs, DN_V2U16 rhs); +DN_API DN_V2U16 operator/ (DN_V2U16 lhs, DN_F32 rhs); +DN_API DN_V2U16 operator/ (DN_V2U16 lhs, int32_t rhs); +DN_API DN_V2U16 & operator*= (DN_V2U16& lhs, DN_V2U16 rhs); +DN_API DN_V2U16 & operator*= (DN_V2U16& lhs, DN_F32 rhs); +DN_API DN_V2U16 & operator*= (DN_V2U16& lhs, int32_t rhs); +DN_API DN_V2U16 & operator/= (DN_V2U16& lhs, DN_V2U16 rhs); +DN_API DN_V2U16 & operator/= (DN_V2U16& lhs, DN_F32 rhs); +DN_API DN_V2U16 & operator/= (DN_V2U16& lhs, int32_t 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_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_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_FromV2U32(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); +DN_API bool operator< (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API bool operator> (DN_V2F32 lhs, DN_V2F32 rhs); + +DN_API DN_V2F32 operator- (DN_V2F32 lhs); +DN_API DN_V2F32 operator- (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API DN_V2F32 operator- (DN_V2F32 lhs, DN_V2I32 rhs); +DN_API DN_V2F32 operator- (DN_V2F32 lhs, DN_F32 rhs); +DN_API DN_V2F32 operator- (DN_V2F32 lhs, int32_t rhs); + +DN_API DN_V2F32 operator+ (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API DN_V2F32 operator+ (DN_V2F32 lhs, DN_V2I32 rhs); +DN_API DN_V2F32 operator+ (DN_V2F32 lhs, DN_F32 rhs); +DN_API DN_V2F32 operator+ (DN_V2F32 lhs, int32_t rhs); + +DN_API DN_V2F32 operator* (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API DN_V2F32 operator* (DN_V2F32 lhs, DN_V2I32 rhs); +DN_API DN_V2F32 operator* (DN_V2F32 lhs, DN_F32 rhs); +DN_API DN_V2F32 operator* (DN_V2F32 lhs, int32_t rhs); + +DN_API DN_V2F32 operator/ (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API DN_V2F32 operator/ (DN_V2F32 lhs, DN_V2I32 rhs); +DN_API DN_V2F32 operator/ (DN_V2F32 lhs, DN_F32 rhs); +DN_API DN_V2F32 operator/ (DN_V2F32 lhs, int32_t rhs); + +DN_API DN_V2F32 & operator*= (DN_V2F32& lhs, DN_V2F32 rhs); +DN_API DN_V2F32 & operator*= (DN_V2F32& lhs, DN_V2I32 rhs); +DN_API DN_V2F32 & operator*= (DN_V2F32& lhs, DN_F32 rhs); +DN_API DN_V2F32 & operator*= (DN_V2F32& lhs, int32_t rhs); + +DN_API DN_V2F32 & operator/= (DN_V2F32& lhs, DN_V2F32 rhs); +DN_API DN_V2F32 & operator/= (DN_V2F32& lhs, DN_V2I32 rhs); +DN_API DN_V2F32 & operator/= (DN_V2F32& lhs, DN_F32 rhs); +DN_API DN_V2F32 & operator/= (DN_V2F32& lhs, int32_t rhs); + +DN_API DN_V2F32 & operator-= (DN_V2F32& lhs, DN_V2F32 rhs); +DN_API DN_V2F32 & operator-= (DN_V2F32& lhs, DN_V2I32 rhs); +DN_API DN_V2F32 & operator-= (DN_V2F32& lhs, DN_F32 rhs); +DN_API DN_V2F32 & operator-= (DN_V2F32& lhs, int32_t rhs); + +DN_API DN_V2F32 & operator+= (DN_V2F32& lhs, DN_V2F32 rhs); +DN_API DN_V2F32 & operator+= (DN_V2F32& lhs, DN_V2I32 rhs); +DN_API DN_V2F32 & operator+= (DN_V2F32& lhs, DN_F32 rhs); +DN_API DN_V2F32 & operator+= (DN_V2F32& lhs, int32_t rhs); + +DN_API DN_V2F32 DN_V2F32_Min (DN_V2F32 a, DN_V2F32 b); +DN_API DN_V2F32 DN_V2F32_Max (DN_V2F32 a, DN_V2F32 b); +DN_API DN_V2F32 DN_V2F32_Abs (DN_V2F32 a); +DN_API DN_F32 DN_V2F32_Dot (DN_V2F32 a, DN_V2F32 b); +DN_API DN_F32 DN_V2F32_LengthSq2V2 (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API bool DN_V2F32_LengthSqIsWithin2V2 (DN_V2F32 lhs, DN_V2F32 rhs, DN_F32 within_amount_sq); +DN_API DN_F32 DN_V2F32_Length2V2 (DN_V2F32 lhs, DN_V2F32 rhs); +DN_API DN_F32 DN_V2F32_LengthSq (DN_V2F32 lhs); +DN_API DN_F32 DN_V2F32_Length (DN_V2F32 lhs); +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_Reflect (DN_V2F32 in, DN_V2F32 surface); +DN_API DN_F32 DN_V2F32_Area (DN_V2F32 a); + +#define DN_V3F32_From1N(x) DN_Literal(DN_V3F32){{(DN_F32)(x), (DN_F32)(x), (DN_F32)(x)}} +#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); +DN_API bool operator< (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API bool operator> (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API DN_V3F32 operator- (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API DN_V3F32 operator- (DN_V3F32 lhs); +DN_API DN_V3F32 operator+ (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API DN_V3F32 operator* (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API DN_V3F32 operator* (DN_V3F32 lhs, DN_F32 rhs); +DN_API DN_V3F32 operator* (DN_V3F32 lhs, int32_t rhs); +DN_API DN_V3F32 operator/ (DN_V3F32 lhs, DN_V3F32 rhs); +DN_API DN_V3F32 operator/ (DN_V3F32 lhs, DN_F32 rhs); +DN_API DN_V3F32 operator/ (DN_V3F32 lhs, int32_t rhs); +DN_API DN_V3F32 & operator*= (DN_V3F32 &lhs, DN_V3F32 rhs); +DN_API DN_V3F32 & operator*= (DN_V3F32 &lhs, DN_F32 rhs); +DN_API DN_V3F32 & operator*= (DN_V3F32 &lhs, int32_t rhs); +DN_API DN_V3F32 & operator/= (DN_V3F32 &lhs, DN_V3F32 rhs); +DN_API DN_V3F32 & operator/= (DN_V3F32 &lhs, DN_F32 rhs); +DN_API DN_V3F32 & operator/= (DN_V3F32 &lhs, int32_t rhs); +DN_API DN_V3F32 & operator-= (DN_V3F32 &lhs, DN_V3F32 rhs); +DN_API DN_V3F32 & operator+= (DN_V3F32 &lhs, DN_V3F32 rhs); +DN_API DN_F32 DN_V3F32_LengthSq (DN_V3F32 a); +DN_API DN_F32 DN_V3F32_Length (DN_V3F32 a); +DN_API DN_V3F32 DN_V3F32_Normalise (DN_V3F32 a); + +DN_U32 const DN_V4_R_MASK_U32 = 0xFF000000; +DN_U32 const DN_V4_G_MASK_U32 = 0x00FF0000; +DN_U32 const DN_V4_B_MASK_U32 = 0x0000FF00; +DN_U32 const DN_V4_A_MASK_U32 = 0x000000FF; + +#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_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_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_FromRGBAU32(DN_U32 u32); +#define DN_V4F32_FromV4Alpha(v4, alpha) DN_V4F32_FromV3And1N(v4.xyz, alpha) +DN_API bool operator== (DN_V4F32 lhs, DN_V4F32 rhs); +DN_API bool operator!= (DN_V4F32 lhs, DN_V4F32 rhs); +DN_API bool operator<= (DN_V4F32 lhs, DN_V4F32 rhs); +DN_API bool operator< (DN_V4F32 lhs, DN_V4F32 rhs); +DN_API bool 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_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_F32 rhs); +DN_API DN_V4F32 operator* (DN_V4F32 lhs, int32_t rhs); +DN_API DN_V4F32 operator/ (DN_V4F32 lhs, DN_F32 rhs); +DN_API DN_V4F32 & operator*= (DN_V4F32 &lhs, DN_V4F32 rhs); +DN_API DN_V4F32 & operator*= (DN_V4F32 &lhs, DN_F32 rhs); +DN_API DN_V4F32 & operator*= (DN_V4F32 &lhs, int32_t 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_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_Scale (DN_V3F32 xyz); +DN_API DN_M4 DN_M4_TranslateF (DN_F32 x, DN_F32 y, DN_F32 z); +DN_API DN_M4 DN_M4_Translate (DN_V3F32 xyz); +DN_API DN_M4 DN_M4_Transpose (DN_M4 mat); +DN_API DN_M4 DN_M4_Rotate (DN_V3F32 axis, DN_F32 radians); +DN_API DN_M4 DN_M4_Orthographic (DN_F32 left, DN_F32 right, DN_F32 bottom, DN_F32 top, DN_F32 z_near, DN_F32 z_far); +DN_API DN_M4 DN_M4_Perspective (DN_F32 fov /*radians*/, DN_F32 aspect, DN_F32 z_near, DN_F32 z_far); +DN_API DN_M4 DN_M4_Add (DN_M4 lhs, DN_M4 rhs); +DN_API DN_M4 DN_M4_Sub (DN_M4 lhs, DN_M4 rhs); +DN_API DN_M4 DN_M4_Mul (DN_M4 lhs, DN_M4 rhs); +DN_API DN_M4 DN_M4_Div (DN_M4 lhs, DN_M4 rhs); +DN_API DN_M4 DN_M4_AddF (DN_M4 lhs, DN_F32 rhs); +DN_API DN_M4 DN_M4_SubF (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_Str8x256 DN_M4_ColumnMajorString (DN_M4 mat); + +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_Translate (DN_V2F32 offset); +DN_API DN_M2x3 DN_M2x3_Scale (DN_V2F32 scale); +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_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); + +#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}}} + +DN_API bool operator== (const DN_Rect& lhs, const DN_Rect& rhs); +DN_API DN_V2F32 DN_Rect_Center (DN_Rect rect); +DN_API bool DN_Rect_ContainsPoint (DN_Rect rect, DN_V2F32 p); +DN_API bool DN_Rect_ContainsRect (DN_Rect a, DN_Rect b); +DN_API DN_Rect DN_Rect_Expand (DN_Rect a, DN_F32 amount); +DN_API DN_Rect DN_Rect_ExpandV2 (DN_Rect a, DN_V2F32 amount); +DN_API bool DN_Rect_Intersects (DN_Rect a, DN_Rect b); +DN_API DN_Rect DN_Rect_Intersection (DN_Rect a, DN_Rect b); +DN_API DN_Rect DN_Rect_Union (DN_Rect a, DN_Rect b); +DN_API DN_RectMinMax DN_Rect_MinMax (DN_Rect a); +DN_API DN_F32 DN_Rect_Area (DN_Rect a); +DN_API DN_V2F32 DN_Rect_InterpolatedPoint (DN_Rect rect, DN_V2F32 t01); +DN_API DN_V2F32 DN_Rect_TopLeft (DN_Rect rect); +DN_API DN_V2F32 DN_Rect_TopRight (DN_Rect rect); +DN_API DN_V2F32 DN_Rect_BottomLeft (DN_Rect rect); +DN_API DN_V2F32 DN_Rect_BottomRight (DN_Rect rect); + +DN_API DN_Rect DN_Rect_CutLeftClip (DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip); +DN_API DN_Rect DN_Rect_CutRightClip (DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip); +DN_API DN_Rect DN_Rect_CutTopClip (DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip); +DN_API DN_Rect DN_Rect_CutBottomClip (DN_Rect *rect, DN_F32 amount, DN_RectCutClip clip); + +#define DN_Rect_CutLeft(rect, amount) DN_Rect_CutLeftClip(rect, amount, DN_RectCutClip_Yes) +#define DN_Rect_CutRight(rect, amount) DN_Rect_CutRightClip(rect, amount, DN_RectCutClip_Yes) +#define DN_Rect_CutTop(rect, amount) DN_Rect_CutTopClip(rect, amount, DN_RectCutClip_Yes) +#define DN_Rect_CutBottom(rect, amount) DN_Rect_CutBottomClip(rect, amount, DN_RectCutClip_Yes) + +#define DN_Rect_CutLeftNoClip(rect, amount) DN_Rect_CutLeftClip(rect, amount, DN_RectCutClip_No) +#define DN_Rect_CutRightNoClip(rect, amount) DN_Rect_CutRightClip(rect, amount, DN_RectCutClip_No) +#define DN_Rect_CutTopNoClip(rect, amount) DN_Rect_CutTopClip(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); +#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_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_Bottom(rect) DN_Literal(DN_RectCut){rect, DN_RectCutSide_Bottom} + +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_F32 DN_Lerp_F32 (DN_F32 a, DN_F32 t, DN_F32 b); +#endif // !defined(DN_MATH_H) +#endif + #if !defined(DN_BASE_H) #error dn_base_inc.h must be included before this #endif diff --git a/Source/Base/dn_base.cpp b/Source/Base/dn_base.cpp index 147e676..aea3bd6 100644 --- a/Source/Base/dn_base.cpp +++ b/Source/Base/dn_base.cpp @@ -1696,6 +1696,13 @@ DN_API DN_Str8x32 DN_Str8x32FromFmt(DN_FMT_ATTRIB char const *fmt, ...) return result; } +DN_API DN_Str8x32 DN_Str8x32FromFmtV(DN_FMT_ATTRIB char const *fmt, va_list args) +{ + DN_Str8x32 result = {}; + DN_FmtVAppend(result.data, &result.size, sizeof(result.data), fmt, args); + return result; +} + DN_API DN_Str8x64 DN_Str8x64FromFmt(DN_FMT_ATTRIB char const *fmt, ...) { va_list args; @@ -1706,6 +1713,13 @@ DN_API DN_Str8x64 DN_Str8x64FromFmt(DN_FMT_ATTRIB char const *fmt, ...) return result; } +DN_API DN_Str8x64 DN_Str8x64FromFmtV(DN_FMT_ATTRIB char const *fmt, va_list args) +{ + DN_Str8x64 result = {}; + DN_FmtVAppend(result.data, &result.size, sizeof(result.data), fmt, args); + return result; +} + DN_API DN_Str8x128 DN_Str8x128FromFmt(DN_FMT_ATTRIB char const *fmt, ...) { va_list args; @@ -1716,6 +1730,13 @@ DN_API DN_Str8x128 DN_Str8x128FromFmt(DN_FMT_ATTRIB char const *fmt, ...) return result; } +DN_API DN_Str8x128 DN_Str8x128FromFmtV(DN_FMT_ATTRIB char const *fmt, va_list args) +{ + DN_Str8x128 result = {}; + DN_FmtVAppend(result.data, &result.size, sizeof(result.data), fmt, args); + return result; +} + DN_API DN_Str8x256 DN_Str8x256FromFmt(DN_FMT_ATTRIB char const *fmt, ...) { va_list args; @@ -1726,6 +1747,13 @@ DN_API DN_Str8x256 DN_Str8x256FromFmt(DN_FMT_ATTRIB char const *fmt, ...) return result; } +DN_API DN_Str8x256 DN_Str8x256FromFmtV(DN_FMT_ATTRIB char const *fmt, va_list args) +{ + DN_Str8x256 result = {}; + DN_FmtVAppend(result.data, &result.size, sizeof(result.data), fmt, args); + return result; +} + DN_API DN_Str8x32 DN_Str8x32FromU64(DN_U64 val, char separator) { DN_Str8x32 result = {}; diff --git a/Source/Base/dn_base.h b/Source/Base/dn_base.h index a1ff99f..d125305 100644 --- a/Source/Base/dn_base.h +++ b/Source/Base/dn_base.h @@ -1007,9 +1007,13 @@ DN_API DN_Str8 DN_Str8FromFmtVArena (DN_Arena *arena, DN DN_API DN_Str8 DN_Str8FromFmtPool (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...); DN_API DN_Str8 DN_Str8FromByteCountType (DN_ByteCountType type); DN_API DN_Str8x32 DN_Str8x32FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x32 DN_Str8x32FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8x64 DN_Str8x64FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x64 DN_Str8x64FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8x128 DN_Str8x128FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x256 DN_Str8x256FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8x256 DN_Str8x256FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x256 DN_Str8x256FromFmtV (DN_FMT_ATTRIB char const *fmt, va_list args); DN_API DN_Str8x32 DN_Str8x32FromU64 (DN_U64 val, char separator); DN_API bool DN_Str8IsAll (DN_Str8 string, DN_Str8IsAllType is_all); DN_API char * DN_Str8End (DN_Str8 string); diff --git a/Source/Extra/dn_tests.cpp b/Source/Extra/dn_tests.cpp index 96be4ae..f035c9b 100644 --- a/Source/Extra/dn_tests.cpp +++ b/Source/Extra/dn_tests.cpp @@ -1938,7 +1938,7 @@ static DN_UTCore DN_Tests_OS() DN_U64 end = DN_OS_PerfCounterNow(); DN_UT_AssertF(&result, wait_result == DN_OSSemaphoreWaitResult_Timeout, "Received wait result %zu", wait_result); DN_F64 elapsed_ms = DN_OS_PerfCounterMs(begin, end); - DN_UT_AssertF(&result, elapsed_ms >= 99 && elapsed_ms <= 120, "Expected to sleep for ~100ms, slept %f ms", elapsed_ms); + DN_UT_AssertF(&result, elapsed_ms >= 80 && elapsed_ms <= 120, "Expected to sleep for ~100ms, slept %f ms", elapsed_ms); } for (DN_UT_Test(&result, "Wait success")) { diff --git a/Source/OS/dn_os_tls.cpp b/Source/OS/dn_os_tls.cpp index 50cc3b5..b5cefb3 100644 --- a/Source/OS/dn_os_tls.cpp +++ b/Source/OS/dn_os_tls.cpp @@ -70,10 +70,10 @@ DN_API void DN_OS_TLSSetCurrentThreadTLS(DN_OSTLS *tls) DN_API DN_OSTLS *DN_OS_TLSGet() { - DN_Assert(g_dn_curr_thread_tls && - "DN must be initialised (via DN_Core_Init) before calling any functions depending on " - "TLS if this is the main thread, OR, the created thread has not called " - "SetCurrentThreadTLS yet so the TLS data structure hasn't been assigned yet"); + DN_RawAssert(g_dn_curr_thread_tls && + "DN must be initialised (via DN_Core_Init) before calling any functions depending on " + "TLS if this is the main thread, OR, the created thread has not called " + "SetCurrentThreadTLS yet so the TLS data structure hasn't been assigned yet"); return g_dn_curr_thread_tls; } diff --git a/single_header_generator.cpp b/single_header_generator.cpp index 2700224..f9fe5a2 100644 --- a/single_header_generator.cpp +++ b/single_header_generator.cpp @@ -79,7 +79,7 @@ static void AppendCppFileLineByLine(DN_Str8Builder *dest, DN_Str8 cpp_path) int main(int argc, char **argv) { DN_Core dn = {}; - DN_Init(&dn, DN_InitFlags_Nil, nullptr); + DN_Init(&dn, DN_InitFlags_OS, nullptr); if (argc != 3) { DN_OS_PrintErrF("USAGE: %s ", argv[0]);