From a17925904d5712a559a0a8997143bffd51bd4f61 Mon Sep 17 00:00:00 2001 From: doylet Date: Tue, 4 Nov 2025 23:31:58 +1100 Subject: [PATCH] Update DN from seasight --- Single_Header/dn_single_header.cpp | 6282 ++++++++++++++-------------- Single_Header/dn_single_header.h | 1480 ++++--- Source/Base/dn_base.cpp | 12 +- Source/Core/dn_core_debug.cpp | 2 +- Source/Core/dn_core_demo.cpp | 6 +- Source/Extra/dn_csv.cpp | 16 +- Source/Extra/dn_tests.cpp | 60 +- Source/OS/dn_os_posix.cpp | 28 +- Source/Standalone/dn_keccak.h | 22 +- single_header_generator.cpp | 78 +- 10 files changed, 3885 insertions(+), 4101 deletions(-) diff --git a/Single_Header/dn_single_header.cpp b/Single_Header/dn_single_header.cpp index b03aae9..b53cfaa 100644 --- a/Single_Header/dn_single_header.cpp +++ b/Single_Header/dn_single_header.cpp @@ -1,4 +1,4 @@ -// Generated by the DN single header generator 2025-10-11 17:43:41 +// Generated by the DN single header generator 2025-11-04 23:31:23 #define DN_BASE_INC_CPP @@ -7,6 +7,12 @@ // DN: Single header generator commented out this header => #include "../dn_base_inc.h" +DN_API bool DN_MemEq(void const *lhs, DN_USize lhs_size, void const *rhs, DN_USize rhs_size) +{ + bool result = lhs_size == rhs_size && DN_Memcmp(lhs, rhs, rhs_size) == 0; + return result; +} + #if !defined(DN_PLATFORM_ARM64) && !defined(DN_PLATFORM_EMSCRIPTEN) #define DN_SUPPORTS_CPU_ID #endif @@ -24,7 +30,7 @@ DN_API DN_U64 DN_AtomicSetValue64(DN_U64 volatile *target, DN_U64 value) do { result = *target; } while (DN_AtomicCompareExchange64(target, value, result) != result); - return DN_CAST(DN_U64) result; + return DN_Cast(DN_U64) result; #elif defined(DN_COMPILER_GCC) || defined(DN_COMPILER_CLANG) DN_U64 result = __sync_lock_test_and_set(target, value); return result; @@ -68,7 +74,7 @@ DN_API DN_USize DN_CPUHasFeatureArray(DN_CPUReport const *report, DN_CPUFeatureQ DN_USize chunk_bit = query->feature % BITS; DN_U64 chunk = report->features[chunk_index]; query->available = chunk & (1ULL << chunk_bit); - result += DN_CAST(int) query->available; + result += DN_Cast(int) query->available; } return result; @@ -118,7 +124,7 @@ DN_API DN_CPUReport DN_CPUGetReport() // NOTE: Query extended function (e.g. eax = 0x8000'0000) for function count + cpu vendor args = {}; - args.eax = DN_CAST(int) EXTENDED_FUNC_BASE_EAX; + args.eax = DN_Cast(int) EXTENDED_FUNC_BASE_EAX; fn_8000_[0] = DN_CPUID(args); } @@ -131,9 +137,9 @@ DN_API DN_CPUReport DN_CPUGetReport() DN_AssertF((STANDARD_FUNC_MAX_EAX + 1) <= DN_ArrayCountI(fn_0000_), "Max standard count is %d", STANDARD_FUNC_MAX_EAX + 1); - DN_AssertF((DN_CAST(DN_ISize) EXTENDED_FUNC_MAX_EAX - EXTENDED_FUNC_BASE_EAX + 1) <= DN_ArrayCountI(fn_8000_), + DN_AssertF((DN_Cast(DN_ISize) EXTENDED_FUNC_MAX_EAX - EXTENDED_FUNC_BASE_EAX + 1) <= DN_ArrayCountI(fn_8000_), "Max extended count is %zu", - DN_CAST(DN_ISize) EXTENDED_FUNC_MAX_EAX - EXTENDED_FUNC_BASE_EAX + 1); + DN_Cast(DN_ISize) EXTENDED_FUNC_MAX_EAX - EXTENDED_FUNC_BASE_EAX + 1); for (int eax = 1; eax <= STANDARD_FUNC_MAX_EAX; eax++) { DN_CPUIDArgs args = {}; @@ -182,7 +188,7 @@ DN_API DN_CPUReport DN_CPUGetReport() // NOTE: Mask bits taken from various manuals // - AMD64 Architecture Programmer's Manual, Volumes 1-5 // - https://en.wikipedia.org/wiki/CPUID#Calling_CPUID - switch (DN_CAST(DN_CPUFeature) ext_index) { + switch (DN_Cast(DN_CPUFeature) ext_index) { case DN_CPUFeature_3DNow: available = (fn_8000_[0x0001].reg.edx & (1 << 31)); break; case DN_CPUFeature_3DNowExt: available = (fn_8000_[0x0001].reg.edx & (1 << 30)); break; case DN_CPUFeature_ABM: available = (fn_8000_[0x0001].reg.ecx & (1 << 5)); break; @@ -241,7 +247,7 @@ DN_API DN_CPUReport DN_CPUGetReport() } if (available) - DN_CPUSetFeature(&result, DN_CAST(DN_CPUFeature) ext_index); + DN_CPUSetFeature(&result, DN_Cast(DN_CPUFeature) ext_index); } #endif // DN_SUPPORTS_CPU_ID return result; @@ -303,7 +309,7 @@ DN_API void DN_BitSetInplace(DN_USize *flags, DN_USize bitfield) DN_API bool DN_BitIsSet(DN_USize bits, DN_USize bits_to_set) { - auto result = DN_CAST(bool)((bits & bits_to_set) == bits_to_set); + auto result = DN_Cast(bool)((bits & bits_to_set) == bits_to_set); return result; } @@ -355,31 +361,31 @@ DN_API DN_U32 DN_SafeSubU32(DN_U32 a, DN_U32 b) // the highest possible rank (unsigned > signed). DN_API int DN_SaturateCastUSizeToInt(DN_USize val) { - int result = DN_Check(DN_CAST(uintmax_t) val <= INT_MAX) ? DN_CAST(int) val : INT_MAX; + int result = DN_Check(DN_Cast(uintmax_t) val <= INT_MAX) ? DN_Cast(int) val : INT_MAX; return result; } DN_API int8_t DN_SaturateCastUSizeToI8(DN_USize val) { - int8_t result = DN_Check(DN_CAST(uintmax_t) val <= INT8_MAX) ? DN_CAST(int8_t) val : INT8_MAX; + int8_t result = DN_Check(DN_Cast(uintmax_t) val <= INT8_MAX) ? DN_Cast(int8_t) val : INT8_MAX; return result; } DN_API DN_I16 DN_SaturateCastUSizeToI16(DN_USize val) { - DN_I16 result = DN_Check(DN_CAST(uintmax_t) val <= INT16_MAX) ? DN_CAST(DN_I16) val : INT16_MAX; + DN_I16 result = DN_Check(DN_Cast(uintmax_t) val <= INT16_MAX) ? DN_Cast(DN_I16) val : INT16_MAX; return result; } DN_API DN_I32 DN_SaturateCastUSizeToI32(DN_USize val) { - DN_I32 result = DN_Check(DN_CAST(uintmax_t) val <= INT32_MAX) ? DN_CAST(DN_I32) val : INT32_MAX; + DN_I32 result = DN_Check(DN_Cast(uintmax_t) val <= INT32_MAX) ? DN_Cast(DN_I32) val : INT32_MAX; return result; } DN_API int64_t DN_SaturateCastUSizeToI64(DN_USize val) { - int64_t result = DN_Check(DN_CAST(uintmax_t) val <= INT64_MAX) ? DN_CAST(int64_t) val : INT64_MAX; + int64_t result = DN_Check(DN_Cast(uintmax_t) val <= INT64_MAX) ? DN_Cast(int64_t) val : INT64_MAX; return result; } @@ -388,56 +394,56 @@ DN_API int64_t DN_SaturateCastUSizeToI64(DN_USize val) // match the highest rank operand. DN_API DN_U8 DN_SaturateCastUSizeToU8(DN_USize val) { - DN_U8 result = DN_Check(val <= UINT8_MAX) ? DN_CAST(DN_U8) val : UINT8_MAX; + DN_U8 result = DN_Check(val <= UINT8_MAX) ? DN_Cast(DN_U8) val : UINT8_MAX; return result; } DN_API DN_U16 DN_SaturateCastUSizeToU16(DN_USize val) { - DN_U16 result = DN_Check(val <= UINT16_MAX) ? DN_CAST(DN_U16) val : UINT16_MAX; + DN_U16 result = DN_Check(val <= UINT16_MAX) ? DN_Cast(DN_U16) val : UINT16_MAX; return result; } DN_API DN_U32 DN_SaturateCastUSizeToU32(DN_USize val) { - DN_U32 result = DN_Check(val <= UINT32_MAX) ? DN_CAST(DN_U32) val : UINT32_MAX; + DN_U32 result = DN_Check(val <= UINT32_MAX) ? DN_Cast(DN_U32) val : UINT32_MAX; return result; } DN_API DN_U64 DN_SaturateCastUSizeToU64(DN_USize val) { - DN_U64 result = DN_Check(DN_CAST(DN_U64) val <= UINT64_MAX) ? DN_CAST(DN_U64) val : UINT64_MAX; + DN_U64 result = DN_Check(DN_Cast(DN_U64) val <= UINT64_MAX) ? DN_Cast(DN_U64) val : UINT64_MAX; return result; } // NOTE: DN_SaturateCastU64To* /////////////////////////////////////////////////////////////// DN_API int DN_SaturateCastU64ToInt(DN_U64 val) { - int result = DN_Check(val <= INT_MAX) ? DN_CAST(int) val : INT_MAX; + int result = DN_Check(val <= INT_MAX) ? DN_Cast(int) val : INT_MAX; return result; } DN_API int8_t DN_SaturateCastU64ToI8(DN_U64 val) { - int8_t result = DN_Check(val <= INT8_MAX) ? DN_CAST(int8_t) val : INT8_MAX; + int8_t result = DN_Check(val <= INT8_MAX) ? DN_Cast(int8_t) val : INT8_MAX; return result; } DN_API DN_I16 DN_SaturateCastU64ToI16(DN_U64 val) { - DN_I16 result = DN_Check(val <= INT16_MAX) ? DN_CAST(DN_I16) val : INT16_MAX; + DN_I16 result = DN_Check(val <= INT16_MAX) ? DN_Cast(DN_I16) val : INT16_MAX; return result; } DN_API DN_I32 DN_SaturateCastU64ToI32(DN_U64 val) { - DN_I32 result = DN_Check(val <= INT32_MAX) ? DN_CAST(DN_I32) val : INT32_MAX; + DN_I32 result = DN_Check(val <= INT32_MAX) ? DN_Cast(DN_I32) val : INT32_MAX; return result; } DN_API int64_t DN_SaturateCastU64ToI64(DN_U64 val) { - int64_t result = DN_Check(val <= INT64_MAX) ? DN_CAST(int64_t) val : INT64_MAX; + int64_t result = DN_Check(val <= INT64_MAX) ? DN_Cast(int64_t) val : INT64_MAX; return result; } @@ -445,25 +451,25 @@ DN_API int64_t DN_SaturateCastU64ToI64(DN_U64 val) // match the highest rank operand. DN_API unsigned int DN_SaturateCastU64ToUInt(DN_U64 val) { - unsigned int result = DN_Check(val <= UINT8_MAX) ? DN_CAST(unsigned int) val : UINT_MAX; + unsigned int result = DN_Check(val <= UINT8_MAX) ? DN_Cast(unsigned int) val : UINT_MAX; return result; } DN_API DN_U8 DN_SaturateCastU64ToU8(DN_U64 val) { - DN_U8 result = DN_Check(val <= UINT8_MAX) ? DN_CAST(DN_U8) val : UINT8_MAX; + DN_U8 result = DN_Check(val <= UINT8_MAX) ? DN_Cast(DN_U8) val : UINT8_MAX; return result; } DN_API DN_U16 DN_SaturateCastU64ToU16(DN_U64 val) { - DN_U16 result = DN_Check(val <= UINT16_MAX) ? DN_CAST(DN_U16) val : UINT16_MAX; + DN_U16 result = DN_Check(val <= UINT16_MAX) ? DN_Cast(DN_U16) val : UINT16_MAX; return result; } DN_API DN_U32 DN_SaturateCastU64ToU32(DN_U64 val) { - DN_U32 result = DN_Check(val <= UINT32_MAX) ? DN_CAST(DN_U32) val : UINT32_MAX; + DN_U32 result = DN_Check(val <= UINT32_MAX) ? DN_Cast(DN_U32) val : UINT32_MAX; return result; } @@ -473,35 +479,35 @@ DN_API DN_U32 DN_SaturateCastU64ToU32(DN_U64 val) DN_API int DN_SaturateCastISizeToInt(DN_ISize val) { DN_Assert(val >= INT_MIN && val <= INT_MAX); - int result = DN_CAST(int) DN_Clamp(val, INT_MIN, INT_MAX); + int result = DN_Cast(int) DN_Clamp(val, INT_MIN, INT_MAX); return result; } DN_API int8_t DN_SaturateCastISizeToI8(DN_ISize val) { DN_Assert(val >= INT8_MIN && val <= INT8_MAX); - int8_t result = DN_CAST(int8_t) DN_Clamp(val, INT8_MIN, INT8_MAX); + int8_t result = DN_Cast(int8_t) DN_Clamp(val, INT8_MIN, INT8_MAX); return result; } DN_API DN_I16 DN_SaturateCastISizeToI16(DN_ISize val) { DN_Assert(val >= INT16_MIN && val <= INT16_MAX); - DN_I16 result = DN_CAST(DN_I16) DN_Clamp(val, INT16_MIN, INT16_MAX); + DN_I16 result = DN_Cast(DN_I16) DN_Clamp(val, INT16_MIN, INT16_MAX); return result; } DN_API DN_I32 DN_SaturateCastISizeToI32(DN_ISize val) { DN_Assert(val >= INT32_MIN && val <= INT32_MAX); - DN_I32 result = DN_CAST(DN_I32) DN_Clamp(val, INT32_MIN, INT32_MAX); + DN_I32 result = DN_Cast(DN_I32) DN_Clamp(val, INT32_MIN, INT32_MAX); return result; } DN_API int64_t DN_SaturateCastISizeToI64(DN_ISize val) { - DN_Assert(DN_CAST(int64_t) val >= INT64_MIN && DN_CAST(int64_t) val <= INT64_MAX); - int64_t result = DN_CAST(int64_t) DN_Clamp(DN_CAST(int64_t) val, INT64_MIN, INT64_MAX); + DN_Assert(DN_Cast(int64_t) val >= INT64_MIN && DN_Cast(int64_t) val <= INT64_MAX); + int64_t result = DN_Cast(int64_t) DN_Clamp(DN_Cast(int64_t) val, INT64_MIN, INT64_MAX); return result; } @@ -512,9 +518,9 @@ DN_API int64_t DN_SaturateCastISizeToI64(DN_ISize val) DN_API unsigned int DN_SaturateCastISizeToUInt(DN_ISize val) { unsigned int result = 0; - if (DN_Check(val >= DN_CAST(DN_ISize) 0)) { - if (DN_Check(DN_CAST(uintmax_t) val <= UINT_MAX)) - result = DN_CAST(unsigned int) val; + if (DN_Check(val >= DN_Cast(DN_ISize) 0)) { + if (DN_Check(DN_Cast(uintmax_t) val <= UINT_MAX)) + result = DN_Cast(unsigned int) val; else result = UINT_MAX; } @@ -524,9 +530,9 @@ DN_API unsigned int DN_SaturateCastISizeToUInt(DN_ISize val) DN_API DN_U8 DN_SaturateCastISizeToU8(DN_ISize val) { DN_U8 result = 0; - if (DN_Check(val >= DN_CAST(DN_ISize) 0)) { - if (DN_Check(DN_CAST(uintmax_t) val <= UINT8_MAX)) - result = DN_CAST(DN_U8) val; + if (DN_Check(val >= DN_Cast(DN_ISize) 0)) { + if (DN_Check(DN_Cast(uintmax_t) val <= UINT8_MAX)) + result = DN_Cast(DN_U8) val; else result = UINT8_MAX; } @@ -536,9 +542,9 @@ DN_API DN_U8 DN_SaturateCastISizeToU8(DN_ISize val) DN_API DN_U16 DN_SaturateCastISizeToU16(DN_ISize val) { DN_U16 result = 0; - if (DN_Check(val >= DN_CAST(DN_ISize) 0)) { - if (DN_Check(DN_CAST(uintmax_t) val <= UINT16_MAX)) - result = DN_CAST(DN_U16) val; + if (DN_Check(val >= DN_Cast(DN_ISize) 0)) { + if (DN_Check(DN_Cast(uintmax_t) val <= UINT16_MAX)) + result = DN_Cast(DN_U16) val; else result = UINT16_MAX; } @@ -548,9 +554,9 @@ DN_API DN_U16 DN_SaturateCastISizeToU16(DN_ISize val) DN_API DN_U32 DN_SaturateCastISizeToU32(DN_ISize val) { DN_U32 result = 0; - if (DN_Check(val >= DN_CAST(DN_ISize) 0)) { - if (DN_Check(DN_CAST(uintmax_t) val <= UINT32_MAX)) - result = DN_CAST(DN_U32) val; + if (DN_Check(val >= DN_Cast(DN_ISize) 0)) { + if (DN_Check(DN_Cast(uintmax_t) val <= UINT32_MAX)) + result = DN_Cast(DN_U32) val; else result = UINT32_MAX; } @@ -560,9 +566,9 @@ DN_API DN_U32 DN_SaturateCastISizeToU32(DN_ISize val) DN_API DN_U64 DN_SaturateCastISizeToU64(DN_ISize val) { DN_U64 result = 0; - if (DN_Check(val >= DN_CAST(DN_ISize) 0)) { - if (DN_Check(DN_CAST(uintmax_t) val <= UINT64_MAX)) - result = DN_CAST(DN_U64) val; + if (DN_Check(val >= DN_Cast(DN_ISize) 0)) { + if (DN_Check(DN_Cast(uintmax_t) val <= UINT64_MAX)) + result = DN_Cast(DN_U64) val; else result = UINT64_MAX; } @@ -575,37 +581,37 @@ DN_API DN_U64 DN_SaturateCastISizeToU64(DN_ISize val) DN_API DN_ISize DN_SaturateCastI64ToISize(int64_t val) { DN_Check(val >= DN_ISIZE_MIN && val <= DN_ISIZE_MAX); - DN_ISize result = DN_CAST(int64_t) DN_Clamp(val, DN_ISIZE_MIN, DN_ISIZE_MAX); + DN_ISize result = DN_Cast(int64_t) DN_Clamp(val, DN_ISIZE_MIN, DN_ISIZE_MAX); return result; } DN_API int8_t DN_SaturateCastI64ToI8(int64_t val) { DN_Check(val >= INT8_MIN && val <= INT8_MAX); - int8_t result = DN_CAST(int8_t) DN_Clamp(val, INT8_MIN, INT8_MAX); + int8_t result = DN_Cast(int8_t) DN_Clamp(val, INT8_MIN, INT8_MAX); return result; } DN_API DN_I16 DN_SaturateCastI64ToI16(int64_t val) { DN_Check(val >= INT16_MIN && val <= INT16_MAX); - DN_I16 result = DN_CAST(DN_I16) DN_Clamp(val, INT16_MIN, INT16_MAX); + DN_I16 result = DN_Cast(DN_I16) DN_Clamp(val, INT16_MIN, INT16_MAX); return result; } DN_API DN_I32 DN_SaturateCastI64ToI32(int64_t val) { DN_Check(val >= INT32_MIN && val <= INT32_MAX); - DN_I32 result = DN_CAST(DN_I32) DN_Clamp(val, INT32_MIN, INT32_MAX); + DN_I32 result = DN_Cast(DN_I32) DN_Clamp(val, INT32_MIN, INT32_MAX); return result; } DN_API unsigned int DN_SaturateCastI64ToUInt(int64_t val) { unsigned int result = 0; - if (DN_Check(val >= DN_CAST(int64_t) 0)) { - if (DN_Check(DN_CAST(uintmax_t) val <= UINT_MAX)) - result = DN_CAST(unsigned int) val; + if (DN_Check(val >= DN_Cast(int64_t) 0)) { + if (DN_Check(DN_Cast(uintmax_t) val <= UINT_MAX)) + result = DN_Cast(unsigned int) val; else result = UINT_MAX; } @@ -615,9 +621,9 @@ DN_API unsigned int DN_SaturateCastI64ToUInt(int64_t val) DN_API DN_ISize DN_SaturateCastI64ToUSize(int64_t val) { DN_USize result = 0; - if (DN_Check(val >= DN_CAST(int64_t) 0)) { - if (DN_Check(DN_CAST(uintmax_t) val <= DN_USIZE_MAX)) - result = DN_CAST(DN_USize) val; + if (DN_Check(val >= DN_Cast(int64_t) 0)) { + if (DN_Check(DN_Cast(uintmax_t) val <= DN_USIZE_MAX)) + result = DN_Cast(DN_USize) val; else result = DN_USIZE_MAX; } @@ -627,9 +633,9 @@ DN_API DN_ISize DN_SaturateCastI64ToUSize(int64_t val) DN_API DN_U8 DN_SaturateCastI64ToU8(int64_t val) { DN_U8 result = 0; - if (DN_Check(val >= DN_CAST(int64_t) 0)) { - if (DN_Check(DN_CAST(uintmax_t) val <= UINT8_MAX)) - result = DN_CAST(DN_U8) val; + if (DN_Check(val >= DN_Cast(int64_t) 0)) { + if (DN_Check(DN_Cast(uintmax_t) val <= UINT8_MAX)) + result = DN_Cast(DN_U8) val; else result = UINT8_MAX; } @@ -639,9 +645,9 @@ DN_API DN_U8 DN_SaturateCastI64ToU8(int64_t val) DN_API DN_U16 DN_SaturateCastI64ToU16(int64_t val) { DN_U16 result = 0; - if (DN_Check(val >= DN_CAST(int64_t) 0)) { - if (DN_Check(DN_CAST(uintmax_t) val <= UINT16_MAX)) - result = DN_CAST(DN_U16) val; + if (DN_Check(val >= DN_Cast(int64_t) 0)) { + if (DN_Check(DN_Cast(uintmax_t) val <= UINT16_MAX)) + result = DN_Cast(DN_U16) val; else result = UINT16_MAX; } @@ -651,9 +657,9 @@ DN_API DN_U16 DN_SaturateCastI64ToU16(int64_t val) DN_API DN_U32 DN_SaturateCastI64ToU32(int64_t val) { DN_U32 result = 0; - if (DN_Check(val >= DN_CAST(int64_t) 0)) { - if (DN_Check(DN_CAST(uintmax_t) val <= UINT32_MAX)) - result = DN_CAST(DN_U32) val; + if (DN_Check(val >= DN_Cast(int64_t) 0)) { + if (DN_Check(DN_Cast(uintmax_t) val <= UINT32_MAX)) + result = DN_Cast(DN_U32) val; else result = UINT32_MAX; } @@ -663,9 +669,9 @@ DN_API DN_U32 DN_SaturateCastI64ToU32(int64_t val) DN_API DN_U64 DN_SaturateCastI64ToU64(int64_t val) { DN_U64 result = 0; - if (DN_Check(val >= DN_CAST(int64_t) 0)) { - if (DN_Check(DN_CAST(uintmax_t) val <= UINT64_MAX)) - result = DN_CAST(DN_U64) val; + if (DN_Check(val >= DN_Cast(int64_t) 0)) { + if (DN_Check(DN_Cast(uintmax_t) val <= UINT64_MAX)) + result = DN_Cast(DN_U64) val; else result = UINT64_MAX; } @@ -675,23 +681,23 @@ DN_API DN_U64 DN_SaturateCastI64ToU64(int64_t val) DN_API int8_t DN_SaturateCastIntToI8(int val) { DN_Check(val >= INT8_MIN && val <= INT8_MAX); - int8_t result = DN_CAST(int8_t) DN_Clamp(val, INT8_MIN, INT8_MAX); + int8_t result = DN_Cast(int8_t) DN_Clamp(val, INT8_MIN, INT8_MAX); return result; } DN_API DN_I16 DN_SaturateCastIntToI16(int val) { DN_Check(val >= INT16_MIN && val <= INT16_MAX); - DN_I16 result = DN_CAST(DN_I16) DN_Clamp(val, INT16_MIN, INT16_MAX); + DN_I16 result = DN_Cast(DN_I16) DN_Clamp(val, INT16_MIN, INT16_MAX); return result; } DN_API DN_U8 DN_SaturateCastIntToU8(int val) { DN_U8 result = 0; - if (DN_Check(val >= DN_CAST(DN_ISize) 0)) { - if (DN_Check(DN_CAST(uintmax_t) val <= UINT8_MAX)) - result = DN_CAST(DN_U8) val; + if (DN_Check(val >= DN_Cast(DN_ISize) 0)) { + if (DN_Check(DN_Cast(uintmax_t) val <= UINT8_MAX)) + result = DN_Cast(DN_U8) val; else result = UINT8_MAX; } @@ -701,9 +707,9 @@ DN_API DN_U8 DN_SaturateCastIntToU8(int val) DN_API DN_U16 DN_SaturateCastIntToU16(int val) { DN_U16 result = 0; - if (DN_Check(val >= DN_CAST(DN_ISize) 0)) { - if (DN_Check(DN_CAST(uintmax_t) val <= UINT16_MAX)) - result = DN_CAST(DN_U16) val; + if (DN_Check(val >= DN_Cast(DN_ISize) 0)) { + if (DN_Check(DN_Cast(uintmax_t) val <= UINT16_MAX)) + result = DN_Cast(DN_U16) val; else result = UINT16_MAX; } @@ -715,7 +721,7 @@ DN_API DN_U32 DN_SaturateCastIntToU32(int val) static_assert(sizeof(val) <= sizeof(DN_U32), "Sanity check to allow simplifying of casting"); DN_U32 result = 0; if (DN_Check(val >= 0)) - result = DN_CAST(DN_U32) val; + result = DN_Cast(DN_U32) val; return result; } @@ -724,7 +730,7 @@ DN_API DN_U64 DN_SaturateCastIntToU64(int val) static_assert(sizeof(val) <= sizeof(DN_U64), "Sanity check to allow simplifying of casting"); DN_U64 result = 0; if (DN_Check(val >= 0)) - result = DN_CAST(DN_U64) val; + result = DN_Cast(DN_U64) val; return result; } @@ -774,6 +780,2106 @@ DN_API DN_F32 DN_EpsilonClampF32(DN_F32 value, DN_F32 target, DN_F32 epsilon) DN_F32 result = (delta < epsilon) ? target : value; return result; } + + +static DN_ArenaBlock *DN_ArenaBlockFromMemFuncs_(DN_U64 reserve, DN_U64 commit, bool track_alloc, bool alloc_can_leak, DN_ArenaMemFuncs mem_funcs) +{ + DN_ArenaBlock *result = nullptr; + switch (mem_funcs.type) { + case DN_ArenaMemFuncType_Nil: + break; + + case DN_ArenaMemFuncType_Basic: { + DN_AssertF(reserve > DN_ARENA_HEADER_SIZE, "%I64u > %I64u", reserve, DN_ARENA_HEADER_SIZE); + result = DN_Cast(DN_ArenaBlock *) mem_funcs.basic_alloc(reserve); + if (!result) + return result; + + result->used = DN_ARENA_HEADER_SIZE; + result->commit = reserve; + result->reserve = reserve; + } break; + + case DN_ArenaMemFuncType_VMem: { + DN_AssertF(mem_funcs.vmem_page_size, "Page size must be set to a non-zero, power of two value"); + DN_Assert(DN_IsPowerOfTwo(mem_funcs.vmem_page_size)); + + DN_USize const page_size = mem_funcs.vmem_page_size; + DN_U64 real_reserve = reserve ? reserve : DN_ARENA_RESERVE_SIZE; + DN_U64 real_commit = commit ? commit : DN_ARENA_COMMIT_SIZE; + real_reserve = DN_AlignUpPowerOfTwo(real_reserve, page_size); + real_commit = DN_Min(DN_AlignUpPowerOfTwo(real_commit, page_size), real_reserve); + DN_AssertF(DN_ARENA_HEADER_SIZE < real_commit && real_commit <= real_reserve, "%I64u < %I64u <= %I64u", DN_ARENA_HEADER_SIZE, real_commit, real_reserve); + + DN_MemCommit mem_commit = real_reserve == real_commit ? DN_MemCommit_Yes : DN_MemCommit_No; + result = DN_Cast(DN_ArenaBlock *) mem_funcs.vmem_reserve(real_reserve, mem_commit, DN_MemPage_ReadWrite); + if (!result) + return result; + + if (mem_commit == DN_MemCommit_No && !mem_funcs.vmem_commit(result, real_commit, DN_MemPage_ReadWrite)) { + mem_funcs.vmem_release(result, real_reserve); + return result; + } + + result->used = DN_ARENA_HEADER_SIZE; + result->commit = real_commit; + result->reserve = real_reserve; + } break; + } + + if (track_alloc && result) + DN_DBGTrackAlloc(result, result->reserve, alloc_can_leak); + + return result; +} + +static DN_ArenaBlock *DN_ArenaBlockFlagsFromMemFuncs_(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs) +{ + bool track_alloc = (flags & DN_ArenaFlags_NoAllocTrack) == 0; + bool alloc_can_leak = flags & DN_ArenaFlags_AllocCanLeak; + DN_ArenaBlock *result = DN_ArenaBlockFromMemFuncs_(reserve, commit, track_alloc, alloc_can_leak, mem_funcs); + if (result && ((flags & DN_ArenaFlags_NoPoison) == 0)) + DN_ASanPoisonMemoryRegion(DN_Cast(char *) result + DN_ARENA_HEADER_SIZE, result->commit - DN_ARENA_HEADER_SIZE); + return result; +} + +static void DN_ArenaUpdateStatsOnNewBlock_(DN_Arena *arena, DN_ArenaBlock const *block) +{ + DN_Assert(arena); + if (block) { + arena->stats.info.used += block->used; + arena->stats.info.commit += block->commit; + arena->stats.info.reserve += block->reserve; + arena->stats.info.blocks += 1; + + arena->stats.hwm.used = DN_Max(arena->stats.hwm.used, arena->stats.info.used); + arena->stats.hwm.commit = DN_Max(arena->stats.hwm.commit, arena->stats.info.commit); + arena->stats.hwm.reserve = DN_Max(arena->stats.hwm.reserve, arena->stats.info.reserve); + arena->stats.hwm.blocks = DN_Max(arena->stats.hwm.blocks, arena->stats.info.blocks); + } +} + +DN_API DN_Arena DN_ArenaFromBuffer(void *buffer, DN_USize size, DN_ArenaFlags flags) +{ + DN_Assert(buffer); + DN_AssertF(DN_ARENA_HEADER_SIZE < size, "Buffer (%zu bytes) too small, need atleast %zu bytes to store arena metadata", size, DN_ARENA_HEADER_SIZE); + DN_AssertF(DN_IsPowerOfTwo(size), "Buffer (%zu bytes) must be a power-of-two", size); + + // NOTE: Init block + DN_ArenaBlock *block = DN_Cast(DN_ArenaBlock *) buffer; + block->commit = size; + block->reserve = size; + block->used = DN_ARENA_HEADER_SIZE; + if (block && ((flags & DN_ArenaFlags_NoPoison) == 0)) + DN_ASanPoisonMemoryRegion(DN_Cast(char *) block + DN_ARENA_HEADER_SIZE, block->commit - DN_ARENA_HEADER_SIZE); + + DN_Arena result = {}; + result.flags = flags | DN_ArenaFlags_NoGrow | DN_ArenaFlags_NoAllocTrack | DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_UserBuffer; + result.curr = block; + DN_ArenaUpdateStatsOnNewBlock_(&result, result.curr); + return result; +} + +DN_API DN_Arena DN_ArenaFromMemFuncs(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs) +{ + DN_Arena result = {}; + result.flags = flags; + result.mem_funcs = mem_funcs; + result.flags |= DN_ArenaFlags_MemFuncs; + result.curr = DN_ArenaBlockFlagsFromMemFuncs_(reserve, commit, flags, mem_funcs); + DN_ArenaUpdateStatsOnNewBlock_(&result, result.curr); + return result; +} + +static void DN_ArenaBlockDeinit_(DN_Arena const *arena, DN_ArenaBlock *block) +{ + DN_USize release_size = block->reserve; + if (DN_BitIsNotSet(arena->flags, DN_ArenaFlags_NoAllocTrack)) + DN_DBGTrackDealloc(block); + DN_ASanUnpoisonMemoryRegion(block, block->commit); + if (arena->flags & DN_ArenaFlags_MemFuncs) { + if (arena->mem_funcs.type == DN_ArenaMemFuncType_Basic) + arena->mem_funcs.basic_dealloc(block); + else + arena->mem_funcs.vmem_release(block, release_size); + } +} + +DN_API void DN_ArenaDeinit(DN_Arena *arena) +{ + for (DN_ArenaBlock *block = arena ? arena->curr : nullptr; block;) { + DN_ArenaBlock *block_to_free = block; + block = block->prev; + DN_ArenaBlockDeinit_(arena, block_to_free); + } + if (arena) + *arena = {}; +} + +DN_API bool DN_ArenaCommitTo(DN_Arena *arena, DN_U64 pos) +{ + if (!arena || !arena->curr) + return false; + + DN_ArenaBlock *curr = arena->curr; + if (pos <= curr->commit) + return true; + + DN_U64 real_pos = pos; + if (!DN_Check(pos <= curr->reserve)) + real_pos = curr->reserve; + + DN_Assert(arena->mem_funcs.vmem_page_size); + DN_USize end_commit = DN_AlignUpPowerOfTwo(real_pos, arena->mem_funcs.vmem_page_size); + DN_USize commit_size = end_commit - curr->commit; + char *commit_ptr = DN_Cast(char *) curr + curr->commit; + if (!arena->mem_funcs.vmem_commit(commit_ptr, commit_size, DN_MemPage_ReadWrite)) + return false; + + bool poison = DN_ASAN_POISON && ((arena->flags & DN_ArenaFlags_NoPoison) == 0); + if (poison) + DN_ASanPoisonMemoryRegion(commit_ptr, commit_size); + + curr->commit = end_commit; + return true; +} + +DN_API bool DN_ArenaCommit(DN_Arena *arena, DN_U64 size) +{ + if (!arena || !arena->curr) + return false; + DN_U64 pos = DN_Min(arena->curr->reserve, arena->curr->commit + size); + bool result = DN_ArenaCommitTo(arena, pos); + return result; +} + +DN_API bool DN_ArenaGrow(DN_Arena *arena, DN_U64 reserve, DN_U64 commit) +{ + if (arena->flags & (DN_ArenaFlags_NoGrow | DN_ArenaFlags_UserBuffer)) + return false; + + bool result = false; + DN_ArenaBlock *new_block = DN_ArenaBlockFlagsFromMemFuncs_(reserve, commit, arena->flags, arena->mem_funcs); + if (new_block) { + result = true; + new_block->prev = arena->curr; + arena->curr = new_block; + new_block->reserve_sum = new_block->prev->reserve_sum + new_block->prev->reserve; + DN_ArenaUpdateStatsOnNewBlock_(arena, arena->curr); + } + return result; +} + +DN_API void *DN_ArenaAlloc(DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZMem z_mem) +{ + if (!arena) + return nullptr; + + if (!arena->curr) { + arena->curr = DN_ArenaBlockFlagsFromMemFuncs_(DN_ARENA_RESERVE_SIZE, DN_ARENA_COMMIT_SIZE, arena->flags, arena->mem_funcs); + DN_ArenaUpdateStatsOnNewBlock_(arena, arena->curr); + } + + if (!arena->curr) + return nullptr; + + try_alloc_again: + DN_ArenaBlock *curr = arena->curr; + bool poison = DN_ASAN_POISON && ((arena->flags & DN_ArenaFlags_NoPoison) == 0); + uint8_t real_align = poison ? DN_Max(align, DN_ASAN_POISON_ALIGNMENT) : align; + DN_U64 offset_pos = DN_AlignUpPowerOfTwo(curr->used, real_align) + (poison ? DN_ASAN_POISON_GUARD_SIZE : 0); + DN_U64 end_pos = offset_pos + size; + DN_U64 alloc_size = end_pos - curr->used; + + if (end_pos > curr->reserve) { + if (arena->flags & (DN_ArenaFlags_NoGrow | DN_ArenaFlags_UserBuffer)) + return nullptr; + DN_USize new_reserve = DN_Max(DN_ARENA_HEADER_SIZE + alloc_size, DN_ARENA_RESERVE_SIZE); + DN_USize new_commit = DN_Max(DN_ARENA_HEADER_SIZE + alloc_size, DN_ARENA_COMMIT_SIZE); + if (!DN_ArenaGrow(arena, new_reserve, new_commit)) + return nullptr; + goto try_alloc_again; + } + + DN_USize prev_arena_commit = curr->commit; + if (end_pos > curr->commit) { + DN_Assert(arena->mem_funcs.vmem_page_size); + DN_Assert(arena->mem_funcs.type == DN_ArenaMemFuncType_VMem); + DN_Assert((arena->flags & DN_ArenaFlags_UserBuffer) == 0); + DN_USize end_commit = DN_AlignUpPowerOfTwo(end_pos, arena->mem_funcs.vmem_page_size); + DN_USize commit_size = end_commit - curr->commit; + char *commit_ptr = DN_Cast(char *) curr + curr->commit; + if (!arena->mem_funcs.vmem_commit(commit_ptr, commit_size, DN_MemPage_ReadWrite)) + return nullptr; + if (poison) + DN_ASanPoisonMemoryRegion(commit_ptr, commit_size); + curr->commit = end_commit; + arena->stats.info.commit += commit_size; + arena->stats.hwm.commit = DN_Max(arena->stats.hwm.commit, arena->stats.info.commit); + } + + void *result = DN_Cast(char *) curr + offset_pos; + curr->used += alloc_size; + arena->stats.info.used += alloc_size; + arena->stats.hwm.used = DN_Max(arena->stats.hwm.used, arena->stats.info.used); + DN_ASanUnpoisonMemoryRegion(result, size); + + if (z_mem == DN_ZMem_Yes) { + DN_USize reused_bytes = DN_Min(prev_arena_commit - offset_pos, size); + DN_Memset(result, 0, reused_bytes); + } + + DN_Assert(arena->stats.hwm.used >= arena->stats.info.used); + DN_Assert(arena->stats.hwm.commit >= arena->stats.info.commit); + DN_Assert(arena->stats.hwm.reserve >= arena->stats.info.reserve); + DN_Assert(arena->stats.hwm.blocks >= arena->stats.info.blocks); + return result; +} + +DN_API void *DN_ArenaAllocContiguous(DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZMem z_mem) +{ + DN_ArenaFlags prev_flags = arena->flags; + arena->flags |= (DN_ArenaFlags_NoGrow | DN_ArenaFlags_NoPoison); + void *memory = DN_ArenaAlloc(arena, size, align, z_mem); + arena->flags = prev_flags; + return memory; +} + +DN_API void *DN_ArenaCopy(DN_Arena *arena, void const *data, DN_U64 size, uint8_t align) +{ + if (!arena || !data || size == 0) + return nullptr; + void *result = DN_ArenaAlloc(arena, size, align, DN_ZMem_No); + if (result) + DN_Memcpy(result, data, size); + return result; +} + +DN_API void DN_ArenaPopTo(DN_Arena *arena, DN_U64 init_used) +{ + if (!arena || !arena->curr) + return; + DN_U64 used = DN_Max(DN_ARENA_HEADER_SIZE, init_used); + DN_ArenaBlock *curr = arena->curr; + while (curr->reserve_sum >= used) { + DN_ArenaBlock *block_to_free = curr; + arena->stats.info.used -= block_to_free->used; + arena->stats.info.commit -= block_to_free->commit; + arena->stats.info.reserve -= block_to_free->reserve; + arena->stats.info.blocks -= 1; + if (arena->flags & DN_ArenaFlags_UserBuffer) + break; + curr = curr->prev; + DN_ArenaBlockDeinit_(arena, block_to_free); + } + + arena->stats.info.used -= curr->used; + arena->curr = curr; + curr->used = used - curr->reserve_sum; + char *poison_ptr = (char *)curr + DN_AlignUpPowerOfTwo(curr->used, DN_ASAN_POISON_ALIGNMENT); + DN_USize poison_size = ((char *)curr + curr->commit) - poison_ptr; + DN_ASanPoisonMemoryRegion(poison_ptr, poison_size); + arena->stats.info.used += curr->used; +} + +DN_API void DN_ArenaPop(DN_Arena *arena, DN_U64 amount) +{ + DN_ArenaBlock *curr = arena->curr; + DN_USize used_sum = curr->reserve_sum + curr->used; + if (!DN_Check(amount <= used_sum)) + amount = used_sum; + DN_USize pop_to = used_sum - amount; + DN_ArenaPopTo(arena, pop_to); +} + +DN_API DN_U64 DN_ArenaPos(DN_Arena const *arena) +{ + DN_U64 result = (arena && arena->curr) ? arena->curr->reserve_sum + arena->curr->used : 0; + return result; +} + +DN_API void DN_ArenaClear(DN_Arena *arena) +{ + DN_ArenaPopTo(arena, 0); +} + +DN_API bool DN_ArenaOwnsPtr(DN_Arena const *arena, void *ptr) +{ + bool result = false; + uintptr_t uint_ptr = DN_Cast(uintptr_t) ptr; + for (DN_ArenaBlock const *block = arena ? arena->curr : nullptr; !result && block; block = block->prev) { + uintptr_t begin = DN_Cast(uintptr_t) block + DN_ARENA_HEADER_SIZE; + uintptr_t end = begin + block->reserve; + result = uint_ptr >= begin && uint_ptr <= end; + } + return result; +} + +DN_API DN_ArenaStats DN_ArenaSumStatsArray(DN_ArenaStats const *array, DN_USize size) +{ + DN_ArenaStats result = {}; + for (DN_ForItSize(it, DN_ArenaStats const, array, size)) { + DN_ArenaStats stats = *it.data; + result.info.used += stats.info.used; + result.info.commit += stats.info.commit; + result.info.reserve += stats.info.reserve; + result.info.blocks += stats.info.blocks; + + result.hwm.used = DN_Max(result.hwm.used, result.info.used); + result.hwm.commit = DN_Max(result.hwm.commit, result.info.commit); + result.hwm.reserve = DN_Max(result.hwm.reserve, result.info.reserve); + result.hwm.blocks = DN_Max(result.hwm.blocks, result.info.blocks); + } + return result; +} + +DN_API DN_ArenaStats DN_ArenaSumStats(DN_ArenaStats lhs, DN_ArenaStats rhs) +{ + DN_ArenaStats array[] = {lhs, rhs}; + DN_ArenaStats result = DN_ArenaSumStatsArray(array, DN_ArrayCountU(array)); + return result; +} + +DN_API DN_ArenaStats DN_ArenaSumArenaArrayToStats(DN_Arena const *array, DN_USize size) +{ + DN_ArenaStats result = {}; + for (DN_USize index = 0; index < size; index++) { + DN_Arena const *arena = array + index; + result = DN_ArenaSumStats(result, arena->stats); + } + return result; +} + +DN_API DN_ArenaTempMem DN_ArenaTempMemBegin(DN_Arena *arena) +{ + DN_ArenaTempMem result = {}; + if (arena) { + DN_ArenaBlock *curr = arena->curr; + result = {arena, curr ? curr->reserve_sum + curr->used : 0}; + } + return result; +}; + +DN_API void DN_ArenaTempMemEnd(DN_ArenaTempMem mem) +{ + DN_ArenaPopTo(mem.arena, mem.used_sum); +}; + +DN_ArenaTempMemScope::DN_ArenaTempMemScope(DN_Arena *arena) +{ + mem = DN_ArenaTempMemBegin(arena); +} + +DN_ArenaTempMemScope::~DN_ArenaTempMemScope() +{ + DN_ArenaTempMemEnd(mem); +} + +// NOTE: DN_Pool /////////////////////////////////////////////////////////////////////////////////// +DN_API DN_Pool DN_PoolFromArena(DN_Arena *arena, uint8_t align) +{ + DN_Pool result = {}; + if (arena) { + result.arena = arena; + result.align = align ? align : DN_POOL_DEFAULT_ALIGN; + } + return result; +} + +DN_API bool DN_PoolIsValid(DN_Pool const *pool) +{ + bool result = pool && pool->arena && pool->align; + return result; +} + +DN_API void *DN_PoolAlloc(DN_Pool *pool, DN_USize size) +{ + void *result = nullptr; + if (!DN_PoolIsValid(pool)) + return result; + + DN_USize const required_size = sizeof(DN_PoolSlot) + pool->align + size; + DN_USize const size_to_slot_offset = 5; // __lzcnt64(32) e.g. DN_PoolSlotSize_32B + DN_USize slot_index = 0; + if (required_size > 32) { + // NOTE: Round up if not PoT as the low bits are set. + DN_USize dist_to_next_msb = DN_CountLeadingZerosUSize(required_size) + 1; + dist_to_next_msb -= DN_Cast(DN_USize)(!DN_IsPowerOfTwo(required_size)); + + DN_USize const register_size = sizeof(DN_USize) * 8; + DN_AssertF(register_size >= (dist_to_next_msb - size_to_slot_offset), "lhs=%zu, rhs=%zu", register_size, (dist_to_next_msb - size_to_slot_offset)); + slot_index = register_size - dist_to_next_msb - size_to_slot_offset; + } + + if (!DN_CheckF(slot_index < DN_PoolSlotSize_Count, "Chunk pool does not support the requested allocation size")) + return result; + + DN_USize slot_size_in_bytes = 1ULL << (slot_index + size_to_slot_offset); + DN_AssertF(required_size <= (slot_size_in_bytes << 0), "slot_index=%zu, lhs=%zu, rhs=%zu", slot_index, required_size, (slot_size_in_bytes << 0)); + DN_AssertF(required_size >= (slot_size_in_bytes >> 1), "slot_index=%zu, lhs=%zu, rhs=%zu", slot_index, required_size, (slot_size_in_bytes >> 1)); + + DN_PoolSlot *slot = nullptr; + if (pool->slots[slot_index]) { + slot = pool->slots[slot_index]; + pool->slots[slot_index] = slot->next; + DN_Memset(slot->data, 0, size); + DN_Assert(DN_IsPowerOfTwoAligned(slot->data, pool->align)); + } else { + void *bytes = DN_ArenaAlloc(pool->arena, slot_size_in_bytes, alignof(DN_PoolSlot), DN_ZMem_Yes); + slot = DN_Cast(DN_PoolSlot *) bytes; + + // NOTE: The raw pointer is round up to the next 'pool->align'-ed + // address ensuring at least 1 byte of padding between the raw pointer + // and the pointer given to the user and that the user pointer is + // aligned to the pool's alignment. + // + // This allows us to smuggle 1 byte behind the user pointer that has + // the offset to the original pointer. + slot->data = DN_Cast(void *) DN_AlignDownPowerOfTwo(DN_Cast(uintptr_t) slot + sizeof(DN_PoolSlot) + pool->align, pool->align); + + uintptr_t offset_to_original_ptr = DN_Cast(uintptr_t) slot->data - DN_Cast(uintptr_t) bytes; + DN_Assert(slot->data > bytes); + DN_Assert(offset_to_original_ptr <= sizeof(DN_PoolSlot) + pool->align); + + // NOTE: Store the offset to the original pointer behind the user's + // pointer. + char *offset_to_original_storage = DN_Cast(char *) slot->data - 1; + DN_Memcpy(offset_to_original_storage, &offset_to_original_ptr, 1); + } + + // NOTE: Smuggle the slot type in the next pointer so that we know, when the + // pointer gets returned which free list to return the pointer to. + result = slot->data; + slot->next = DN_Cast(DN_PoolSlot *) slot_index; + return result; +} + +DN_API void DN_PoolDealloc(DN_Pool *pool, void *ptr) +{ + if (!DN_PoolIsValid(pool) || !ptr) + return; + + DN_Assert(DN_ArenaOwnsPtr(pool->arena, ptr)); + + char const *one_byte_behind_ptr = DN_Cast(char *) ptr - 1; + DN_USize offset_to_original_ptr = 0; + DN_Memcpy(&offset_to_original_ptr, one_byte_behind_ptr, 1); + DN_Assert(offset_to_original_ptr <= sizeof(DN_PoolSlot) + pool->align); + + char *original_ptr = DN_Cast(char *) ptr - offset_to_original_ptr; + DN_PoolSlot *slot = DN_Cast(DN_PoolSlot *) original_ptr; + DN_PoolSlotSize slot_index = DN_Cast(DN_PoolSlotSize)(DN_Cast(uintptr_t) slot->next); + DN_Assert(slot_index < DN_PoolSlotSize_Count); + + slot->next = pool->slots[slot_index]; + pool->slots[slot_index] = slot; +} + +DN_API void *DN_PoolCopy(DN_Pool *pool, void const *data, DN_U64 size, uint8_t align) +{ + if (!pool || !data || size == 0) + return nullptr; + + // TODO: Hmm should align be part of the alloc interface in general? I'm not going to worry + // about this until we crash because of misalignment. + DN_Assert(pool->align >= align); + + void *result = DN_PoolAlloc(pool, size); + if (result) + DN_Memcpy(result, data, size); + return result; +} + +DN_API bool DN_CharIsAlphabet(char ch) +{ + bool result = (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); + return result; +} + +DN_API bool DN_CharIsDigit(char ch) +{ + bool result = (ch >= '0' && ch <= '9'); + return result; +} + +DN_API bool DN_CharIsAlphaNum(char ch) +{ + bool result = DN_CharIsAlphabet(ch) || DN_CharIsDigit(ch); + return result; +} + +DN_API bool DN_CharIsWhitespace(char ch) +{ + bool result = (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); + return result; +} + +DN_API bool DN_CharIsHex(char ch) +{ + bool result = ((ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') || (ch >= '0' && ch <= '9')); + return result; +} + +DN_API char DN_CharToLower(char ch) +{ + char result = ch; + if (result >= 'A' && result <= 'Z') + result += 'a' - 'A'; + return result; +} + +DN_API char DN_CharToUpper(char ch) +{ + char result = ch; + if (result >= 'a' && result <= 'z') + result -= 'a' - 'A'; + return result; +} + +DN_API DN_U64FromResult DN_U64FromStr8(DN_Str8 string, char separator) +{ + // NOTE: Argument check + DN_U64FromResult result = {}; + if (string.size == 0) { + result.success = true; + return result; + } + + // NOTE: Sanitize input/output + DN_Str8 trim_string = DN_Str8TrimWhitespaceAround(string); + if (trim_string.size == 0) { + result.success = true; + return result; + } + + // NOTE: Handle prefix '+' + DN_USize start_index = 0; + if (!DN_CharIsDigit(trim_string.data[0])) { + if (trim_string.data[0] != '+') + return result; + start_index++; + } + + // NOTE: Convert the string number to the binary number + for (DN_USize index = start_index; index < trim_string.size; index++) { + char ch = trim_string.data[index]; + if (index) { + if (separator != 0 && ch == separator) + continue; + } + + if (!DN_CharIsDigit(ch)) + return result; + + result.value = DN_SafeMulU64(result.value, 10); + uint64_t digit = ch - '0'; + result.value = DN_SafeAddU64(result.value, digit); + } + + result.success = true; + return result; +} + +DN_API DN_U64FromResult DN_U64FromPtr(void const *data, DN_USize size, char separator) +{ + DN_Str8 str8 = DN_Str8FromPtr((char *)data, size); + DN_U64FromResult result = DN_U64FromStr8(str8, separator); + return result; +} + +DN_API DN_U64 DN_U64FromPtrUnsafe(void const *data, DN_USize size, char separator) +{ + DN_U64FromResult from = DN_U64FromPtr(data, size, separator); + DN_U64 result = from.value; + DN_Assert(from.success); + return result; +} + +DN_API DN_U64FromResult DN_U64FromHexPtr(void const *hex, DN_USize hex_count) +{ + char *hex_ptr = DN_Cast(char *) hex; + if (hex_count >= 2 && hex_ptr[0] == '0' && (hex_ptr[1] == 'x' || hex_ptr[1] == 'X')) { + hex_ptr += 2; + hex_count -= 2; + } + + DN_U64FromResult result = {}; + DN_USize max_hex_count = sizeof(DN_U64) * 2; + DN_USize count = DN_Min(max_hex_count, hex_count); + DN_Assert(hex_count <= max_hex_count); + for (DN_USize index = 0; index < count; index++) { + char ch = hex_ptr[index]; + DN_U8 val = DN_U8FromHexNibble(ch); + if (val == 0xFF) + return result; + result.value = (result.value << 4) | val; + } + result.success = true; + return result; +} + +DN_API DN_U64 DN_U64FromHexPtrUnsafe(void const *hex, DN_USize hex_count) +{ + DN_U64FromResult from = DN_U64FromHexPtr(hex, hex_count); + DN_U64 result = from.value; + DN_Assert(from.success); + return result; +} + +DN_API DN_U64FromResult DN_U64FromHexStr8(DN_Str8 hex) +{ + DN_U64FromResult result = DN_U64FromHexPtr(hex.data, hex.size); + return result; +} + +DN_API DN_U64 DN_U64FromHexStr8Unsafe(DN_Str8 hex) +{ + DN_U64 result = DN_U64FromHexPtrUnsafe(hex.data, hex.size); + return result; +} + +DN_API DN_I64FromResult DN_I64FromStr8(DN_Str8 string, char separator) +{ + // NOTE: Argument check + DN_I64FromResult result = {}; + if (string.size == 0) { + result.success = true; + return result; + } + + // NOTE: Sanitize input/output + DN_Str8 trim_string = DN_Str8TrimWhitespaceAround(string); + if (trim_string.size == 0) { + result.success = true; + return result; + } + + bool negative = false; + DN_USize start_index = 0; + if (!DN_CharIsDigit(trim_string.data[0])) { + negative = (trim_string.data[start_index] == '-'); + if (!negative && trim_string.data[0] != '+') + return result; + start_index++; + } + + // NOTE: Convert the string number to the binary number + for (DN_USize index = start_index; index < trim_string.size; index++) { + char ch = trim_string.data[index]; + if (index) { + if (separator != 0 && ch == separator) + continue; + } + + if (!DN_CharIsDigit(ch)) + return result; + + result.value = DN_SafeMulU64(result.value, 10); + uint64_t digit = ch - '0'; + result.value = DN_SafeAddU64(result.value, digit); + } + + if (negative) + result.value *= -1; + + result.success = true; + return result; +} + +DN_API DN_I64FromResult DN_I64FromPtr(void const *data, DN_USize size, char separator) +{ + DN_Str8 str8 = DN_Str8FromPtr((char *)data, size); + DN_I64FromResult result = DN_I64FromStr8(str8, separator); + return result; +} + +DN_API DN_I64 DN_I64FromPtrUnsafe(void const *data, DN_USize size, char separator) +{ + DN_I64FromResult from = DN_I64FromPtr(data, size, separator); + DN_I64 result = from.value; + DN_Assert(from.success); + return result; +} + +DN_API DN_FmtAppendResult DN_FmtVAppend(char *buf, DN_USize *buf_size, DN_USize buf_max, char const *fmt, va_list args) +{ + DN_FmtAppendResult result = {}; + result.size_req = DN_VSNPrintF(buf + *buf_size, DN_Cast(int)(buf_max - *buf_size), fmt, args); + *buf_size += result.size_req; + if (*buf_size >= (buf_max - 1)) + *buf_size = buf_max - 1; + DN_Assert(*buf_size <= (buf_max - 1)); + result.str8 = DN_Str8FromPtr(buf, *buf_size); + result.truncated = result.str8.size != result.size_req; + return result; +} + +DN_API DN_FmtAppendResult DN_FmtAppend(char *buf, DN_USize *buf_size, DN_USize buf_max, char const *fmt, ...) +{ + va_list args; + va_start(args, fmt); + DN_FmtAppendResult result = DN_FmtVAppend(buf, buf_size, buf_max - (*buf_size), fmt, args); + va_end(args); + return result; +} + +DN_API DN_FmtAppendResult DN_FmtAppendTruncate(char *buf, DN_USize *buf_size, DN_USize buf_max, DN_Str8 truncator, char const *fmt, ...) +{ + va_list args; + va_start(args, fmt); + DN_FmtAppendResult result = DN_FmtVAppend(buf, buf_size, buf_max, fmt, args); + if (result.truncated) + DN_Memcpy(result.str8.data + result.str8.size - truncator.size, truncator.data, truncator.size); + va_end(args); + return result; +} + +DN_API DN_USize DN_FmtSize(DN_FMT_ATTRIB char const *fmt, ...) +{ + va_list args; + va_start(args, fmt); + DN_USize result = DN_VSNPrintF(nullptr, 0, fmt, args); + va_end(args); + return result; +} + +DN_API DN_USize DN_FmtVSize(DN_FMT_ATTRIB char const *fmt, va_list args) +{ + va_list args_copy; + va_copy(args_copy, args); + DN_USize result = DN_VSNPrintF(nullptr, 0, fmt, args_copy); + va_end(args_copy); + return result; +} + +DN_API DN_USize DN_CStr8Size(char const *src) +{ + DN_USize result = 0; + for (; src && src[0] != 0; src++, result++) + ; + return result; +} + +DN_API DN_USize DN_CStr16Size(wchar_t const *src) +{ + DN_USize result = 0; + for (; src && src[0] != 0; src++, result++) + ; + return result; +} + +DN_API bool DN_Str16Eq(DN_Str16 lhs, DN_Str16 rhs) +{ + if (lhs.size != rhs.size) + return false; + bool result = (DN_Memcmp(lhs.data, rhs.data, lhs.size) == 0); + return result; +} + +DN_API DN_Str8 DN_Str8FromCStr8(char const *src) +{ + DN_USize size = DN_CStr8Size(src); + DN_Str8 result = DN_Str8FromPtr(src, size); + return result; +} + +DN_API DN_Str8 DN_Str8FromArena(DN_Arena *arena, DN_USize size, DN_ZMem z_mem) +{ + DN_Str8 result = {}; + result.data = DN_ArenaNewArray(arena, char, size + 1, z_mem); + if (result.data) + result.size = size; + result.data[result.size] = 0; + return result; +} + +DN_API DN_Str8 DN_Str8FromPool(DN_Pool *pool, DN_USize size) +{ + DN_Str8 result = {}; + result.data = DN_PoolNewArray(pool, char, size + 1); + if (result.data) + result.size = size; + result.data[result.size] = 0; + return result; +} + +DN_API DN_Str8 DN_Str8FromStr8Arena(DN_Arena *arena, DN_Str8 string) +{ + DN_Str8 result = {}; + result.data = DN_Cast(char *) DN_ArenaAlloc(arena, string.size + 1, alignof(char), DN_ZMem_No); + if (result.data) { + DN_Memcpy(result.data, string.data, string.size); + result.data[string.size] = 0; + result.size = string.size; + } + return result; +} + +DN_API DN_Str8 DN_Str8FromStr8Pool(DN_Pool *pool, DN_Str8 string) +{ + DN_Str8 result = {}; + result.data = DN_Cast(char *) DN_PoolAlloc(pool, string.size + 1); + if (result.data) { + DN_Memcpy(result.data, string.data, string.size); + result.data[string.size] = 0; + result.size = string.size; + } + return result; +} + +DN_API DN_Str8 DN_Str8FromFmtArena(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...) +{ + va_list va; + va_start(va, fmt); + DN_Str8 result = DN_Str8FromFmtVArena(arena, fmt, va); + va_end(va); + return result; +} + +DN_API DN_Str8 DN_Str8FromFmtVArena(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args) +{ + DN_USize size = DN_FmtVSize(fmt, args); + DN_Str8 result = DN_Str8FromArena(arena, size, DN_ZMem_No); + if (result.data) { + DN_USize written = 0; + DN_FmtVAppend(result.data, &written, result.size + 1, fmt, args); + DN_Assert(written == result.size); + } + return result; +} + +DN_API DN_Str8 DN_Str8FromFmtPool(DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...) +{ + va_list args; + va_start(args, fmt); + DN_USize size = DN_FmtVSize(fmt, args); + DN_Str8 result = DN_Str8FromPool(pool, size); + if (result.data) { + DN_USize written = 0; + DN_FmtVAppend(result.data, &written, result.size + 1, fmt, args); + DN_Assert(written == result.size); + } + va_end(args); + return result; +} + +DN_API DN_Str8x32 DN_Str8x32FromFmt(DN_FMT_ATTRIB char const *fmt, ...) +{ + va_list args; + va_start(args, fmt); + DN_Str8x32 result = {}; + DN_FmtVAppend(result.data, &result.size, sizeof(result.data), fmt, args); + va_end(args); + return result; +} + +DN_API DN_Str8x64 DN_Str8x64FromFmt(DN_FMT_ATTRIB char const *fmt, ...) +{ + va_list args; + va_start(args, fmt); + DN_Str8x64 result = {}; + DN_FmtVAppend(result.data, &result.size, sizeof(result.data), fmt, args); + va_end(args); + return result; +} + +DN_API DN_Str8x128 DN_Str8x128FromFmt(DN_FMT_ATTRIB char const *fmt, ...) +{ + va_list args; + va_start(args, fmt); + DN_Str8x128 result = {}; + DN_FmtVAppend(result.data, &result.size, sizeof(result.data), fmt, args); + va_end(args); + return result; +} + +DN_API DN_Str8x256 DN_Str8x256FromFmt(DN_FMT_ATTRIB char const *fmt, ...) +{ + va_list args; + va_start(args, fmt); + DN_Str8x256 result = {}; + DN_FmtVAppend(result.data, &result.size, sizeof(result.data), fmt, args); + va_end(args); + return result; +} + +DN_API DN_Str8x32 DN_Str8x32FromU64(DN_U64 val, char separator) +{ + DN_Str8x32 result = {}; + DN_Str8x32 temp = DN_Str8x32FromFmt("%" PRIu64, val); + DN_USize temp_index = 0; + + // NOTE: Write the digits the first, up to [0, 2] digits that do not need a thousandth separator + DN_USize range_without_separator = temp.size % 3; + for (; temp_index < range_without_separator; temp_index++) + result.data[result.size++] = temp.data[temp_index]; + + // NOTE: Write the subsequent digits and every 3rd digit, add the seperator + DN_USize digit_counter = 0; + for (; temp_index < temp.size; temp_index++, digit_counter++) { + if (separator && temp_index && (digit_counter % 3 == 0)) + result.data[result.size++] = separator; + result.data[result.size++] = temp.data[temp_index]; + } + return result; +} + + +DN_API bool DN_Str8IsAll(DN_Str8 string, DN_Str8IsAllType is_all) +{ + bool result = string.size; + if (!result) + return result; + + switch (is_all) { + case DN_Str8IsAllType_Digits: { + for (DN_USize index = 0; result && index < string.size; index++) + result = string.data[index] >= '0' && string.data[index] <= '9'; + } break; + + case DN_Str8IsAllType_Hex: { + DN_Str8 trimmed = DN_Str8TrimPrefix(string, DN_Str8Lit("0x"), DN_Str8EqCase_Insensitive); + for (DN_USize index = 0; result && index < trimmed.size; index++) { + char ch = trimmed.data[index]; + result = (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'); + } + } break; + } + + return result; +} + +DN_API char *DN_Str8End(DN_Str8 string) +{ + char *result = string.data + string.size; + return result; +} + +DN_API DN_Str8 DN_Str8Slice(DN_Str8 string, DN_USize offset, DN_USize size) +{ + DN_Str8 result = DN_Str8FromPtr(string.data, 0); + if (string.size == 0) + return result; + + DN_USize capped_offset = DN_Min(offset, string.size); + DN_USize max_size = string.size - capped_offset; + DN_USize capped_size = DN_Min(size, max_size); + result = DN_Str8FromPtr(string.data + capped_offset, capped_size); + return result; +} + +DN_API DN_Str8 DN_Str8Advance(DN_Str8 string, DN_USize amount) +{ + DN_Str8 result = DN_Str8Slice(string, amount, DN_USIZE_MAX); + return result; +} + +DN_API DN_Str8 DN_Str8NextLine(DN_Str8 string) +{ + DN_Str8 result = DN_Str8BSplit(string, DN_Str8Lit("\n")).rhs; + return result; +} + +DN_API DN_Str8BSplitResult DN_Str8BSplitArray(DN_Str8 string, DN_Str8 const *find, DN_USize find_size) +{ + DN_Str8BSplitResult result = {}; + if (string.size == 0 || !find || find_size == 0) + return result; + + result.lhs = string; + for (size_t index = 0; !result.rhs.data && index < string.size; index++) { + for (DN_USize find_index = 0; find_index < find_size; find_index++) { + DN_Str8 find_item = find[find_index]; + DN_Str8 string_slice = DN_Str8Slice(string, index, find_item.size); + if (DN_Str8Eq(string_slice, find_item)) { + result.lhs.size = index; + result.rhs.data = string_slice.data + find_item.size; + result.rhs.size = string.size - (index + find_item.size); + break; + } + } + } + + return result; +} + +DN_API DN_Str8BSplitResult DN_Str8BSplit(DN_Str8 string, DN_Str8 find) +{ + DN_Str8BSplitResult result = DN_Str8BSplitArray(string, &find, 1); + return result; +} + +DN_API DN_Str8BSplitResult DN_Str8BSplitLastArray(DN_Str8 string, DN_Str8 const *find, DN_USize find_size) +{ + DN_Str8BSplitResult result = {}; + if (string.size == 0 || !find || find_size == 0) + return result; + + result.lhs = string; + for (size_t index = string.size - 1; !result.rhs.data && index < string.size; index--) { + for (DN_USize find_index = 0; find_index < find_size; find_index++) { + DN_Str8 find_item = find[find_index]; + DN_Str8 string_slice = DN_Str8Slice(string, index, find_item.size); + if (DN_Str8Eq(string_slice, find_item)) { + result.lhs.size = index; + result.rhs.data = string_slice.data + find_item.size; + result.rhs.size = string.size - (index + find_item.size); + break; + } + } + } + + return result; +} + +DN_API DN_Str8BSplitResult DN_Str8BSplitLast(DN_Str8 string, DN_Str8 find) +{ + DN_Str8BSplitResult result = DN_Str8BSplitLastArray(string, &find, 1); + return result; +} + +DN_API DN_USize DN_Str8Split(DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_USize splits_count, DN_Str8SplitIncludeEmptyStrings mode) +{ + DN_USize result = 0; // The number of splits in the actual string. + if (string.size == 0 || delimiter.size == 0 || delimiter.size <= 0) + return result; + + DN_Str8BSplitResult split = {}; + DN_Str8 first = string; + do { + split = DN_Str8BSplit(first, delimiter); + if (split.lhs.size || mode == DN_Str8SplitIncludeEmptyStrings_Yes) { + if (splits && result < splits_count) + splits[result] = split.lhs; + result++; + } + first = split.rhs; + } while (first.size); + + return result; +} + +DN_API DN_Str8SplitResult DN_Str8SplitArena(DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode) +{ + DN_Str8SplitResult result = {}; + DN_USize count = DN_Str8Split(string, delimiter, /*splits*/ nullptr, /*count*/ 0, mode); + result.data = DN_ArenaNewArray(arena, DN_Str8, count, DN_ZMem_No); + if (result.data) { + result.count = DN_Str8Split(string, delimiter, result.data, count, mode); + DN_Assert(count == result.count); + } + return result; +} + +DN_API DN_Str8FindResult DN_Str8FindStr8Array(DN_Str8 string, DN_Str8 const *find, DN_USize find_size, DN_Str8EqCase eq_case) +{ + DN_Str8FindResult result = {}; + for (DN_USize index = 0; !result.found && index < string.size; index++) { + for (DN_USize find_index = 0; find_index < find_size; find_index++) { + DN_Str8 find_item = find[find_index]; + DN_Str8 string_slice = DN_Str8Slice(string, index, find_item.size); + if (DN_Str8Eq(string_slice, find_item, eq_case)) { + result.found = true; + result.index = index; + result.start_to_before_match = DN_Str8FromPtr(string.data, index); + result.match = DN_Str8FromPtr(string.data + index, find_item.size); + result.match_to_end_of_buffer = DN_Str8FromPtr(result.match.data, string.size - index); + result.after_match_to_end_of_buffer = DN_Str8Advance(result.match_to_end_of_buffer, find_item.size); + break; + } + } + } + return result; +} + +DN_API DN_Str8FindResult DN_Str8FindStr8(DN_Str8 string, DN_Str8 find, DN_Str8EqCase eq_case) +{ + DN_Str8FindResult result = DN_Str8FindStr8Array(string, &find, 1, eq_case); + return result; +} + +DN_API DN_Str8FindResult DN_Str8Find(DN_Str8 string, uint32_t flags) +{ + DN_Str8FindResult result = {}; + for (size_t index = 0; !result.found && index < string.size; index++) { + result.found |= ((flags & DN_Str8FindFlag_Digit) && DN_CharIsDigit(string.data[index])); + result.found |= ((flags & DN_Str8FindFlag_Alphabet) && DN_CharIsAlphabet(string.data[index])); + result.found |= ((flags & DN_Str8FindFlag_Whitespace) && DN_CharIsWhitespace(string.data[index])); + result.found |= ((flags & DN_Str8FindFlag_Plus) && string.data[index] == '+'); + result.found |= ((flags & DN_Str8FindFlag_Minus) && string.data[index] == '-'); + if (result.found) { + result.index = index; + result.match = DN_Str8FromPtr(string.data + index, 1); + result.match_to_end_of_buffer = DN_Str8FromPtr(result.match.data, string.size - index); + result.after_match_to_end_of_buffer = DN_Str8Advance(result.match_to_end_of_buffer, 1); + } + } + return result; +} + +DN_API DN_Str8 DN_Str8Segment(DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char) +{ + if (!segment_size || src.size == 0) { + DN_Str8 result = DN_Str8FromStr8Arena(arena, src); + return result; + } + + DN_USize segments = src.size / segment_size; + if (src.size % segment_size == 0) + segments--; + + DN_USize segment_counter = 0; + DN_Str8 result = DN_Str8FromArena(arena, src.size + segments, DN_ZMem_Yes); + DN_USize write_index = 0; + for (DN_ForIndexU(src_index, src.size)) { + result.data[write_index++] = src.data[src_index]; + if ((src_index + 1) % segment_size == 0 && segment_counter < segments) { + result.data[write_index++] = segment_char; + segment_counter++; + } + DN_AssertF(write_index <= result.size, "result.size=%zu, write_index=%zu", result.size, write_index); + } + + DN_AssertF(write_index == result.size, "result.size=%zu, write_index=%zu", result.size, write_index); + return result; +} + +DN_API DN_Str8 DN_Str8ReverseSegment(DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char) +{ + if (!segment_size || src.size == 0) { + DN_Str8 result = DN_Str8FromStr8Arena(arena, src); + return result; + } + + DN_USize segments = src.size / segment_size; + if (src.size % segment_size == 0) + segments--; + + DN_USize write_counter = 0; + DN_USize segment_counter = 0; + DN_Str8 result = DN_Str8FromArena(arena, src.size + segments, DN_ZMem_Yes); + DN_USize write_index = result.size - 1; + + DN_MSVC_WARNING_PUSH + DN_MSVC_WARNING_DISABLE(6293) // NOTE: Ill-defined loop + for (size_t src_index = src.size - 1; src_index < src.size; src_index--) { + DN_MSVC_WARNING_POP + result.data[write_index--] = src.data[src_index]; + if (++write_counter % segment_size == 0 && segment_counter < segments) { + result.data[write_index--] = segment_char; + segment_counter++; + } + } + + DN_Assert(write_index == SIZE_MAX); + return result; +} + +DN_API bool DN_Str8Eq(DN_Str8 lhs, DN_Str8 rhs, DN_Str8EqCase eq_case) +{ + if (lhs.size != rhs.size) + return false; + bool result = true; + switch (eq_case) { + case DN_Str8EqCase_Sensitive: { + result = (DN_Memcmp(lhs.data, rhs.data, lhs.size) == 0); + } break; + + case DN_Str8EqCase_Insensitive: { + for (DN_USize index = 0; index < lhs.size && result; index++) + result = (DN_CharToLower(lhs.data[index]) == DN_CharToLower(rhs.data[index])); + } break; + } + return result; +} + +DN_API bool DN_Str8EqInsensitive(DN_Str8 lhs, DN_Str8 rhs) +{ + bool result = DN_Str8Eq(lhs, rhs, DN_Str8EqCase_Insensitive); + return result; +} + +DN_API bool DN_Str8StartsWith(DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case) +{ + DN_Str8 substring = {string.data, DN_Min(prefix.size, string.size)}; + bool result = DN_Str8Eq(substring, prefix, eq_case); + return result; +} + +DN_API bool DN_Str8StartsWithInsensitive(DN_Str8 string, DN_Str8 prefix) +{ + bool result = DN_Str8StartsWith(string, prefix, DN_Str8EqCase_Insensitive); + return result; +} + +DN_API bool DN_Str8EndsWith(DN_Str8 string, DN_Str8 suffix, DN_Str8EqCase eq_case) +{ + DN_Str8 substring = {string.data + string.size - suffix.size, DN_Min(string.size, suffix.size)}; + bool result = DN_Str8Eq(substring, suffix, eq_case); + return result; +} + +DN_API bool DN_Str8EndsWithInsensitive(DN_Str8 string, DN_Str8 suffix) +{ + bool result = DN_Str8EndsWith(string, suffix, DN_Str8EqCase_Insensitive); + return result; +} + +DN_API bool DN_Str8HasChar(DN_Str8 string, char ch) +{ + bool result = false; + for (DN_USize index = 0; !result && index < string.size; index++) + result = string.data[index] == ch; + return result; +} + +DN_API DN_Str8 DN_Str8TrimPrefix(DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case) +{ + DN_Str8 result = string; + if (DN_Str8StartsWith(string, prefix, eq_case)) { + result.data += prefix.size; + result.size -= prefix.size; + } + return result; +} + +DN_API DN_Str8 DN_Str8TrimHexPrefix(DN_Str8 string) +{ + DN_Str8 result = DN_Str8TrimPrefix(string, DN_Str8Lit("0x"), DN_Str8EqCase_Insensitive); + return result; +} + +DN_API DN_Str8 DN_Str8TrimSuffix(DN_Str8 string, DN_Str8 suffix, DN_Str8EqCase eq_case) +{ + DN_Str8 result = string; + if (DN_Str8EndsWith(string, suffix, eq_case)) + result.size -= suffix.size; + return result; +} + +DN_API DN_Str8 DN_Str8TrimAround(DN_Str8 string, DN_Str8 trim_string) +{ + DN_Str8 result = DN_Str8TrimPrefix(string, trim_string); + result = DN_Str8TrimSuffix(result, trim_string); + return result; +} + +DN_API DN_Str8 DN_Str8TrimHeadWhitespace(DN_Str8 string) +{ + DN_Str8 result = string; + if (string.size == 0) + return result; + + char const *start = string.data; + char const *end = string.data + string.size; + while (start < end && DN_CharIsWhitespace(start[0])) + start++; + + result = DN_Str8FromPtr(start, end - start); + return result; +} + +DN_API DN_Str8 DN_Str8TrimTailWhitespace(DN_Str8 string) +{ + DN_Str8 result = string; + if (string.size == 0) + return result; + + char const *start = string.data; + char const *end = string.data + string.size; + while (end > start && DN_CharIsWhitespace(end[-1])) + end--; + + result = DN_Str8FromPtr(start, end - start); + return result; +} + +DN_API DN_Str8 DN_Str8TrimWhitespaceAround(DN_Str8 string) +{ + DN_Str8 result = DN_Str8TrimHeadWhitespace(string); + result = DN_Str8TrimTailWhitespace(result); + return result; +} + +DN_API DN_Str8 DN_Str8TrimByteOrderMark(DN_Str8 string) +{ + DN_Str8 result = string; + if (result.size == 0) + return result; + + // TODO(dn): This is little endian + DN_Str8 UTF8_BOM = DN_Str8Lit("\xEF\xBB\xBF"); + DN_Str8 UTF16_BOM_BE = DN_Str8Lit("\xEF\xFF"); + DN_Str8 UTF16_BOM_LE = DN_Str8Lit("\xFF\xEF"); + DN_Str8 UTF32_BOM_BE = DN_Str8Lit("\x00\x00\xFE\xFF"); + DN_Str8 UTF32_BOM_LE = DN_Str8Lit("\xFF\xFE\x00\x00"); + + result = DN_Str8TrimPrefix(result, UTF8_BOM, DN_Str8EqCase_Sensitive); + result = DN_Str8TrimPrefix(result, UTF16_BOM_BE, DN_Str8EqCase_Sensitive); + result = DN_Str8TrimPrefix(result, UTF16_BOM_LE, DN_Str8EqCase_Sensitive); + result = DN_Str8TrimPrefix(result, UTF32_BOM_BE, DN_Str8EqCase_Sensitive); + result = DN_Str8TrimPrefix(result, UTF32_BOM_LE, DN_Str8EqCase_Sensitive); + return result; +} + +DN_API DN_Str8 DN_Str8FileNameFromPath(DN_Str8 path) +{ + DN_Str8 separators[] = {DN_Str8Lit("/"), DN_Str8Lit("\\")}; + DN_Str8BSplitResult split = DN_Str8BSplitLastArray(path, separators, DN_ArrayCountU(separators)); + DN_Str8 result = split.rhs.size ? split.rhs : split.lhs; + return result; +} + +DN_API DN_Str8 DN_Str8FileNameNoExtension(DN_Str8 path) +{ + DN_Str8 file_name = DN_Str8FileNameFromPath(path); + DN_Str8 result = DN_Str8FilePathNoExtension(file_name); + return result; +} + +DN_API DN_Str8 DN_Str8FilePathNoExtension(DN_Str8 path) +{ + DN_Str8BSplitResult split = DN_Str8BSplitLast(path, DN_Str8Lit(".")); + DN_Str8 result = split.lhs; + return result; +} + +DN_API DN_Str8 DN_Str8FileExtension(DN_Str8 path) +{ + DN_Str8BSplitResult split = DN_Str8BSplitLast(path, DN_Str8Lit(".")); + DN_Str8 result = split.rhs; + return result; +} + +DN_API DN_Str8 DN_Str8FileDirectoryFromPath(DN_Str8 path) +{ + DN_Str8 separators[] = {DN_Str8Lit("/"), DN_Str8Lit("\\")}; + DN_Str8BSplitResult split = DN_Str8BSplitLastArray(path, separators, DN_ArrayCountU(separators)); + DN_Str8 result = split.lhs; + return result; +} + +DN_API DN_Str8 DN_Str8AppendF(DN_Arena *arena, DN_Str8 string, char const *fmt, ...) +{ + va_list args; + va_start(args, fmt); + DN_Str8 result = DN_Str8AppendFV(arena, string, fmt, args); + va_end(args); + return result; +} + +DN_API DN_Str8 DN_Str8AppendFV(DN_Arena *arena, DN_Str8 string, char const *fmt, va_list args) +{ + // TODO: Calculate size and write into one buffer instead of 2 appends + DN_Str8 append = DN_Str8FromFmtVArena(arena, fmt, args); + DN_Str8 result = DN_Str8FromArena(arena, string.size + append.size, DN_ZMem_No); + DN_Memcpy(result.data, string.data, string.size); + DN_Memcpy(result.data + string.size, append.data, append.size); + return result; +} + +DN_API DN_Str8 DN_Str8FillF(DN_Arena *arena, DN_USize count, char const *fmt, ...) +{ + va_list args; + va_start(args, fmt); + DN_Str8 result = DN_Str8FillFV(arena, count, fmt, args); + va_end(args); + return result; +} + +DN_API DN_Str8 DN_Str8FillFV(DN_Arena *arena, DN_USize count, char const *fmt, va_list args) +{ + DN_Str8 fill = DN_Str8FromFmtVArena(arena, fmt, args); + DN_Str8 result = DN_Str8FromArena(arena, count * fill.size, DN_ZMem_No); + for (DN_USize index = 0; index < count; index++) { + void *dest = result.data + (index * fill.size); + DN_Memcpy(dest, fill.data, fill.size); + } + return result; +} + +DN_API void DN_Str8Remove(DN_Str8 *string, DN_USize offset, DN_USize size) +{ + if (!string || string->size) + return; + + char *end = string->data + string->size; + char *dest = DN_Min(string->data + offset, end); + char *src = DN_Min(string->data + offset + size, end); + DN_USize bytes_to_move = end - src; + DN_Memmove(dest, src, bytes_to_move); + string->size -= bytes_to_move; +} + +DN_API DN_Str8TruncateResult DN_Str8TruncateMiddle(DN_Arena *arena, DN_Str8 str8, DN_U32 side_size, DN_Str8 truncator) +{ + DN_Str8TruncateResult result = {}; + if (str8.size <= (side_size * 2)) { + result.str8 = DN_Str8FromStr8Arena(arena, str8); + return result; + } + + DN_Str8 head = DN_Str8Slice(str8, 0, side_size); + DN_Str8 tail = DN_Str8Slice(str8, str8.size - side_size, side_size); + DN_MSVC_WARNING_PUSH + DN_MSVC_WARNING_DISABLE(6284) // Object passed as _Param_(3) when a string is required in call to 'DN_Str8FromFmtArena' Actual type: 'struct DN_Str8' + result.str8 = DN_Str8FromFmtArena(arena, "%S%S%S", head, truncator, tail); + DN_MSVC_WARNING_POP + result.truncated = true; + return result; +} + +DN_API DN_Str8 DN_Str8Lower(DN_Arena *arena, DN_Str8 string) +{ + DN_Str8 result = DN_Str8FromStr8Arena(arena, string); + for (DN_ForIndexU(index, result.size)) + result.data[index] = DN_CharToLower(result.data[index]); + return result; +} + +DN_API DN_Str8 DN_Str8Upper(DN_Arena *arena, DN_Str8 string) +{ + DN_Str8 result = DN_Str8FromStr8Arena(arena, string); + for (DN_ForIndexU(index, result.size)) + result.data[index] = DN_CharToUpper(result.data[index]); + return result; +} + +DN_API DN_Str8Builder DN_Str8BuilderFromArena(DN_Arena *arena) +{ + DN_Str8Builder result = {}; + result.arena = arena; + return result; +} + +DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrRef(DN_Arena *arena, DN_Str8 const *strings, DN_USize size) +{ + DN_Str8Builder result = DN_Str8BuilderFromArena(arena); + DN_Str8BuilderAppendArrayRef(&result, strings, size); + return result; +} + +DN_API DN_Str8Builder DN_Str8BuilderFromStr8PtrCopy(DN_Arena *arena, DN_Str8 const *strings, DN_USize size) +{ + DN_Str8Builder result = DN_Str8BuilderFromArena(arena); + DN_Str8BuilderAppendArrayCopy(&result, strings, size); + return result; +} + +DN_API DN_Str8Builder DN_Str8BuilderFromBuilder(DN_Arena *arena, DN_Str8Builder const *builder) +{ + DN_Str8Builder result = DN_Str8BuilderFromArena(arena); + DN_Str8BuilderAppendBuilderCopy(&result, builder); + return result; +} + +DN_API bool DN_Str8BuilderAddArrayRef(DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize size, DN_Str8BuilderAdd add) +{ + if (!builder) + return false; + + if (!strings || size <= 0) + return true; + + DN_Str8Link *links = DN_ArenaNewArray(builder->arena, DN_Str8Link, size, DN_ZMem_No); + if (!links) + return false; + + if (add == DN_Str8BuilderAdd_Append) { + for (DN_ForIndexU(index, size)) { + DN_Str8 string = strings[index]; + DN_Str8Link *link = links + index; + + link->string = string; + link->next = NULL; + + if (builder->head) + builder->tail->next = link; + else + builder->head = link; + + builder->tail = link; + builder->count++; + builder->string_size += string.size; + } + } else { + DN_Assert(add == DN_Str8BuilderAdd_Prepend); + DN_MSVC_WARNING_PUSH + DN_MSVC_WARNING_DISABLE(6293) // NOTE: Ill-defined loop + for (DN_USize index = size - 1; index < size; index--) { + DN_MSVC_WARNING_POP + DN_Str8 string = strings[index]; + DN_Str8Link *link = links + index; + link->string = string; + link->next = builder->head; + builder->head = link; + if (!builder->tail) + builder->tail = link; + builder->count++; + builder->string_size += string.size; + } + } + return true; +} + +DN_API bool DN_Str8BuilderAddArrayCopy(DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize size, DN_Str8BuilderAdd add) +{ + if (!builder) + return false; + + if (!strings || size <= 0) + return true; + + DN_ArenaTempMem tmp_mem = DN_ArenaTempMemBegin(builder->arena); + bool result = true; + DN_Str8 *strings_copy = DN_ArenaNewArray(builder->arena, DN_Str8, size, DN_ZMem_No); + for (DN_ForIndexU(index, size)) { + strings_copy[index] = DN_Str8FromStr8Arena(builder->arena, strings[index]); + if (strings_copy[index].size != strings[index].size) { + result = false; + break; + } + } + + if (result) + result = DN_Str8BuilderAddArrayRef(builder, strings_copy, size, add); + + if (!result) + DN_ArenaTempMemEnd(tmp_mem); + + return result; +} + +DN_API bool DN_Str8BuilderAddFV(DN_Str8Builder *builder, DN_Str8BuilderAdd add, DN_FMT_ATTRIB char const *fmt, va_list args) +{ + DN_Str8 string = DN_Str8FromFmtVArena(builder->arena, fmt, args); + DN_ArenaTempMem temp_mem = DN_ArenaTempMemBegin(builder->arena); + bool result = DN_Str8BuilderAddArrayRef(builder, &string, 1, add); + if (!result) + DN_ArenaTempMemEnd(temp_mem); + return result; +} + +DN_API bool DN_Str8BuilderAppendRef(DN_Str8Builder *builder, DN_Str8 string) +{ + bool result = DN_Str8BuilderAddArrayRef(builder, &string, 1, DN_Str8BuilderAdd_Append); + return result; +} + +DN_API bool DN_Str8BuilderAppendCopy(DN_Str8Builder *builder, DN_Str8 string) +{ + bool result = DN_Str8BuilderAddArrayCopy(builder, &string, 1, DN_Str8BuilderAdd_Append); + return result; +} + +DN_API bool DN_Str8BuilderAppendF(DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...) +{ + va_list args; + va_start(args, fmt); + bool result = DN_Str8BuilderAppendFV(builder, fmt, args); + va_end(args); + return result; +} + +DN_API bool DN_Str8BuilderAppendBytesRef(DN_Str8Builder *builder, void const *ptr, DN_USize size) +{ + DN_Str8 input = DN_Str8FromPtr(ptr, size); + bool result = DN_Str8BuilderAppendRef(builder, input); + return result; +} + +DN_API bool DN_Str8BuilderAppendBytesCopy(DN_Str8Builder *builder, void const *ptr, DN_USize size) +{ + DN_Str8 input = DN_Str8FromPtr(ptr, size); + bool result = DN_Str8BuilderAppendCopy(builder, input); + return result; +} + +static bool DN_Str8BuilderAppendBuilder_(DN_Str8Builder *dest, DN_Str8Builder const *src, bool copy) +{ + if (!dest) + return false; + if (!src) + return true; + + DN_ArenaTempMemBegin(dest->arena); + DN_Str8Link *links = DN_ArenaNewArray(dest->arena, DN_Str8Link, src->count, DN_ZMem_No); + if (!links) + return false; + + DN_Str8Link *first = nullptr; + DN_Str8Link *last = nullptr; + DN_USize link_index = 0; + bool result = true; + for (DN_Str8Link const *it = src->head; it; it = it->next) { + DN_Str8Link *link = links + link_index++; + link->next = nullptr; + link->string = it->string; + + if (copy) { + link->string = DN_Str8FromStr8Arena(dest->arena, it->string); + if (link->string.size != it->string.size) { + result = false; + break; + } + } + + if (last) + last->next = link; + else + first = link; + last = link; + } + + if (result) { + if (dest->head) + dest->tail->next = first; + else + dest->head = first; + dest->tail = last; + dest->count += src->count; + dest->string_size += src->string_size; + } + return true; +} + +DN_API bool DN_Str8BuilderAppendBuilderRef(DN_Str8Builder *dest, DN_Str8Builder const *src) +{ + bool result = DN_Str8BuilderAppendBuilder_(dest, src, false); + return result; +} + +DN_API bool DN_Str8BuilderAppendBuilderCopy(DN_Str8Builder *dest, DN_Str8Builder const *src) +{ + bool result = DN_Str8BuilderAppendBuilder_(dest, src, true); + return result; +} + +DN_API bool DN_Str8BuilderPrependRef(DN_Str8Builder *builder, DN_Str8 string) +{ + bool result = DN_Str8BuilderAddArrayRef(builder, &string, 1, DN_Str8BuilderAdd_Prepend); + return result; +} + +DN_API bool DN_Str8BuilderPrependCopy(DN_Str8Builder *builder, DN_Str8 string) +{ + bool result = DN_Str8BuilderAddArrayCopy(builder, &string, 1, DN_Str8BuilderAdd_Prepend); + return result; +} + +DN_API bool DN_Str8BuilderPrependF(DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...) +{ + va_list args; + va_start(args, fmt); + bool result = DN_Str8BuilderPrependFV(builder, fmt, args); + va_end(args); + return result; +} + +DN_API bool DN_Str8BuilderErase(DN_Str8Builder *builder, DN_Str8 string) +{ + for (DN_Str8Link **it = &builder->head; *it; it = &((*it)->next)) { + if (DN_Str8Eq((*it)->string, string)) { + *it = (*it)->next; + builder->string_size -= string.size; + builder->count -= 1; + return true; + } + } + return false; +} + +DN_API DN_Str8 DN_Str8BuilderBuild(DN_Str8Builder const *builder, DN_Arena *arena) +{ + DN_Str8 result = DN_Str8BuilderBuildDelimited(builder, DN_Str8Lit(""), arena); + return result; +} + +DN_API DN_Str8 DN_Str8BuilderBuildDelimited(DN_Str8Builder const *builder, DN_Str8 delimiter, DN_Arena *arena) +{ + DN_Str8 result = DN_ZeroInit; + if (!builder || builder->string_size <= 0 || builder->count <= 0) + return result; + + DN_USize size_for_delimiter = delimiter.size ? ((builder->count - 1) * delimiter.size) : 0; + result.data = DN_ArenaNewArray(arena, + char, + builder->string_size + size_for_delimiter + 1 /*null terminator*/, + DN_ZMem_No); + if (!result.data) + return result; + + for (DN_Str8Link *link = builder->head; link; link = link->next) { + DN_Memcpy(result.data + result.size, link->string.data, link->string.size); + result.size += link->string.size; + if (link->next && delimiter.size) { + DN_Memcpy(result.data + result.size, delimiter.data, delimiter.size); + result.size += delimiter.size; + } + } + + result.data[result.size] = 0; + DN_Assert(result.size == builder->string_size + size_for_delimiter); + return result; +} + +DN_API DN_Slice DN_Str8BuilderBuildSlice(DN_Str8Builder const *builder, DN_Arena *arena) +{ + DN_Slice result = DN_ZeroInit; + if (!builder || builder->string_size <= 0 || builder->count <= 0) + return result; + + result = DN_Slice_Alloc(arena, builder->count, DN_ZMem_No); + if (!result.data) + return result; + + DN_USize slice_index = 0; + for (DN_Str8Link *link = builder->head; link; link = link->next) + result.data[slice_index++] = DN_Str8FromStr8Arena(arena, link->string); + + DN_Assert(slice_index == builder->count); + return result; +} + +// NOTE: DN_Char /////////////////////////////////////////////////////////////////////////////////// +// NOTE: DN_UTF //////////////////////////////////////////////////////////////////////////////////// +DN_API int DN_UTF8_EncodeCodepoint(uint8_t utf8[4], uint32_t codepoint) +{ + // NOTE: Table from https://www.reedbeta.com/blog/programmers-intro-to-unicode/ + // ----------------------------------------+----------------------------+--------------------+ + // UTF-8 (binary) | Code point (binary) | Range | + // ----------------------------------------+----------------------------+--------------------+ + // 0xxx'xxxx | xxx'xxxx | U+0000 - U+007F | + // 110x'xxxx 10yy'yyyy | xxx'xxyy'yyyy | U+0080 - U+07FF | + // 1110'xxxx 10yy'yyyy 10zz'zzzz | xxxx'yyyy'yyzz'zzzz | U+0800 - U+FFFF | + // 1111'0xxx 10yy'yyyy 10zz'zzzz 10ww'wwww | x'xxyy'yyyy'zzzz'zzww'wwww | U+10000 - U+10FFFF | + // ----------------------------------------+----------------------------+--------------------+ + + if (codepoint <= 0b0111'1111) { + utf8[0] = DN_Cast(uint8_t) codepoint; + return 1; + } + + if (codepoint <= 0b0111'1111'1111) { + utf8[0] = (0b1100'0000 | ((codepoint >> 6) & 0b01'1111)); // x + utf8[1] = (0b1000'0000 | ((codepoint >> 0) & 0b11'1111)); // y + return 2; + } + + if (codepoint <= 0b1111'1111'1111'1111) { + utf8[0] = (0b1110'0000 | ((codepoint >> 12) & 0b00'1111)); // x + utf8[1] = (0b1000'0000 | ((codepoint >> 6) & 0b11'1111)); // y + utf8[2] = (0b1000'0000 | ((codepoint >> 0) & 0b11'1111)); // z + return 3; + } + + if (codepoint <= 0b1'1111'1111'1111'1111'1111) { + utf8[0] = (0b1111'0000 | ((codepoint >> 18) & 0b00'0111)); // x + utf8[1] = (0b1000'0000 | ((codepoint >> 12) & 0b11'1111)); // y + utf8[2] = (0b1000'0000 | ((codepoint >> 6) & 0b11'1111)); // z + utf8[3] = (0b1000'0000 | ((codepoint >> 0) & 0b11'1111)); // w + return 4; + } + + return 0; +} + +DN_API int DN_UTF16_EncodeCodepoint(uint16_t utf16[2], uint32_t codepoint) +{ + // NOTE: Table from https://www.reedbeta.com/blog/programmers-intro-to-unicode/ + // ----------------------------------------+------------------------------------+------------------+ + // UTF-16 (binary) | Code point (binary) | Range | + // ----------------------------------------+------------------------------------+------------------+ + // xxxx'xxxx'xxxx'xxxx | xxxx'xxxx'xxxx'xxxx | U+0000???U+FFFF | + // 1101'10xx'xxxx'xxxx 1101'11yy'yyyy'yyyy | xxxx'xxxx'xxyy'yyyy'yyyy + 0x10000 | U+10000???U+10FFFF | + // ----------------------------------------+------------------------------------+------------------+ + + if (codepoint <= 0b1111'1111'1111'1111) { + utf16[0] = DN_Cast(uint16_t) codepoint; + return 1; + } + + if (codepoint <= 0b1111'1111'1111'1111'1111) { + uint32_t surrogate_codepoint = codepoint + 0x10000; + utf16[0] = 0b1101'1000'0000'0000 | ((surrogate_codepoint >> 10) & 0b11'1111'1111); // x + utf16[1] = 0b1101'1100'0000'0000 | ((surrogate_codepoint >> 0) & 0b11'1111'1111); // y + return 2; + } + + return 0; +} + + +DN_API DN_U8 DN_U8FromHexNibble(char hex) +{ + bool digit = hex >= '0' && hex <= '9'; + bool upper = hex >= 'A' && hex <= 'F'; + bool lower = hex >= 'a' && hex <= 'f'; + DN_U8 result = 0xFF; + if (digit) + result = hex - '0'; + if (upper) + result = hex - 'A' + 10; + if (lower) + result = hex - 'a' + 10; + return result; +} + +DN_API DN_NibbleFromU8Result DN_NibbleFromU8(DN_U8 u8) +{ + static char const *table = "0123456789abcdef"; + DN_U8 lhs = (u8 >> 0) & 0xF; + DN_U8 rhs = (u8 >> 4) & 0xF; + DN_NibbleFromU8Result result = {}; + result.nibble0 = table[rhs]; + result.nibble1 = table[lhs]; + return result; +} + +DN_API DN_USize DN_BytesFromHexPtr(void const *hex, DN_USize hex_count, void *bytes, DN_USize bytes_count) +{ + DN_USize result = 0; + DN_U8 const *hex_u8 = DN_Cast(DN_U8 const *) hex; + if (hex_count >= 2 && hex_u8[0] == '0' && (hex_u8[1] == 'x' || hex_u8[1] == 'X')) { + hex_u8 += 2; + hex_count -= 2; + } + + if (hex_count > (bytes_count * 2)) + return result; + + DN_U8 *ptr = DN_Cast(DN_U8 *)bytes; + for (DN_USize index = 0; index < hex_count; index += 2) { + DN_U8 nibble0 = DN_U8FromHexNibble(hex_u8[index + 0]); + DN_U8 nibble1 = DN_U8FromHexNibble(hex_u8[index + 1]); + if (nibble0 == 0xFF || nibble1 == 0xFF) + return result; + *ptr++ = nibble0 << 4 | nibble1 << 0; + result++; + } + return result; +} + +DN_API DN_Str8 DN_BytesFromHexPtrArena(void const *hex, DN_USize hex_size, DN_Arena *arena) +{ + DN_Assert(hex_size % 2 == 0); + DN_Str8 result = {}; + result.data = DN_ArenaNewArray(arena, char, hex_size / 2, DN_ZMem_No); + if (result.data) + result.size = DN_BytesFromHexPtr(hex, hex_size, result.data, hex_size / 2); + return result; +} + +DN_API DN_USize DN_BytesFromHexStr8(DN_Str8 hex, void *dest, DN_USize dest_count) +{ + DN_USize result = DN_BytesFromHexPtr(hex.data, hex.size, dest, dest_count); + return result; +} + +DN_API DN_Str8 DN_BytesFromHexStr8Arena(DN_Str8 hex, DN_Arena *arena) +{ + DN_Str8 result = DN_BytesFromHexPtrArena(hex.data, hex.size, arena); + return result; +} + +DN_API DN_U8x16 DN_BytesFromHex32Ptr(void const *hex, DN_USize hex_count) +{ + DN_U8x16 result = {}; + DN_Assert(hex_count / 2 == sizeof result.data); + DN_USize bytes_written = DN_BytesFromHexPtr(hex, hex_count, result.data, sizeof result); + DN_Assert(bytes_written == sizeof result.data); + return result; +} + +DN_API DN_U8x32 DN_BytesFromHex64Ptr(void const *hex, DN_USize hex_count) +{ + DN_U8x32 result = {}; + DN_Assert(hex_count / 2 == sizeof result.data); + DN_USize bytes_written = DN_BytesFromHexPtr(hex, hex_count, result.data, sizeof result); + DN_Assert(bytes_written == sizeof result.data); + return result; +} + +DN_API DN_HexU64Str8 DN_HexFromU64(DN_U64 value, DN_HexFromU64Type type) +{ + DN_HexU64Str8 result = {}; + DN_HexFromBytesPtr(&value, sizeof(value), result.data, sizeof(result.data)); + if (type == DN_HexFromU64Type_Uppercase) { + for (DN_USize index = 0; index < result.size; index++) + result.data[index] = DN_CharToUpper(result.data[index]); + } + return result; +} + +DN_API DN_USize DN_HexFromBytesPtr(void const *bytes, DN_USize bytes_count, void *hex, DN_USize hex_count) +{ + DN_USize result = 0; + if ((bytes_count * 2) != hex_count) + return result; + DN_U8 const *src_u8 = DN_Cast(DN_U8 const *)bytes; + DN_U8 *ptr = DN_Cast(DN_U8 *)hex; + for (DN_USize index = 0; index < bytes_count; index++) { + DN_NibbleFromU8Result to_nibbles = DN_NibbleFromU8(src_u8[index]); + *ptr++ = to_nibbles.nibble0; + *ptr++ = to_nibbles.nibble1; + result += 2; + } + return result; +} + +DN_API DN_Str8 DN_HexFromBytesPtrArena(void const *bytes, DN_USize bytes_count, DN_Arena *arena) +{ + DN_Str8 result = {}; + result.data = DN_ArenaNewArray(arena, char, bytes_count * 2, DN_ZMem_No); + if (result.data) + result.size = DN_HexFromBytesPtr(bytes, bytes_count, result.data, bytes_count * 2); + return result; +} + +DN_API DN_Hex32 DN_HexFromBytes16Ptr(void const *bytes, DN_USize bytes_count) +{ + DN_Hex32 result = {}; + DN_Assert(bytes_count * 2 == sizeof result.data); + DN_USize hex_written = DN_HexFromBytesPtr(bytes, bytes_count, result.data, sizeof result.data); + DN_Assert(hex_written == sizeof result.data); + return result; +} + +DN_API DN_Hex64 DN_HexFromBytes32Ptr(void const *bytes, DN_USize bytes_count) +{ + DN_Hex64 result = {}; + DN_Assert(bytes_count * 2 == sizeof result.data); + DN_USize hex_written = DN_HexFromBytesPtr(bytes, bytes_count, result.data, sizeof result.data); + DN_Assert(hex_written == sizeof result.data); + return result; +} + +DN_API DN_Hex128 DN_HexFromBytes64Ptr(void const *bytes, DN_USize bytes_count) +{ + DN_Hex128 result = {}; + DN_Assert(bytes_count * 2 == sizeof result.data); + DN_USize hex_written = DN_HexFromBytesPtr(bytes, bytes_count, result.data, sizeof result.data); + DN_Assert(hex_written == sizeof result.data); + return result; +} + +DN_API DN_Str8x128 DN_AgeStr8FromMsU64(DN_U64 duration_ms, DN_AgeUnit units) +{ + DN_Str8x128 result = {}; + DN_U64 remainder_ms = duration_ms; + if (units & DN_AgeUnit_FractionalSec) { + units |= DN_AgeUnit_Sec; + units &= ~DN_AgeUnit_Ms; + } + + if (units & DN_AgeUnit_Year) { + DN_USize value_usize = remainder_ms / (DN_SecFromYears(1) * 1000); + remainder_ms -= DN_SecFromYears(value_usize) * 1000; + if (value_usize) + DN_FmtAppend(result.data, &result.size, sizeof(result.data), "%s%zuyr", result.size ? " " : "", value_usize); + } + + if (units & DN_AgeUnit_Week) { + DN_USize value_usize = remainder_ms / (DN_SecFromWeeks(1) * 1000); + remainder_ms -= DN_SecFromWeeks(value_usize) * 1000; + if (value_usize) + DN_FmtAppend(result.data, &result.size, sizeof(result.data), "%s%zuw", result.size ? " " : "", value_usize); + } + + if (units & DN_AgeUnit_Day) { + DN_USize value_usize = remainder_ms / (DN_SecFromDays(1) * 1000); + remainder_ms -= DN_SecFromDays(value_usize) * 1000; + if (value_usize) + DN_FmtAppend(result.data, &result.size, sizeof(result.data), "%s%zud", result.size ? " " : "", value_usize); + } + + if (units & DN_AgeUnit_Hr) { + DN_USize value_usize = remainder_ms / (DN_SecFromHours(1) * 1000); + remainder_ms -= DN_SecFromHours(value_usize) * 1000; + if (value_usize) + DN_FmtAppend(result.data, &result.size, sizeof(result.data), "%s%zuh", result.size ? " " : "", value_usize); + } + + if (units & DN_AgeUnit_Min) { + DN_USize value_usize = remainder_ms / (DN_SecFromMins(1) * 1000); + remainder_ms -= DN_SecFromMins(value_usize) * 1000; + if (value_usize) + DN_FmtAppend(result.data, &result.size, sizeof(result.data), "%s%zum", result.size ? " " : "", value_usize); + } + + if (units & DN_AgeUnit_Sec) { + if (units & DN_AgeUnit_FractionalSec) { + DN_F64 remainder_s = remainder_ms / 1000.0; + DN_FmtAppend(result.data, &result.size, sizeof(result.data), "%s%.3fs", result.size ? " " : "", remainder_s); + remainder_ms = 0; + } else { + DN_USize value_usize = remainder_ms / 1000; + remainder_ms -= DN_Cast(DN_USize)(value_usize * 1000); + if (value_usize) + DN_FmtAppend(result.data, &result.size, sizeof(result.data), "%s%zus", result.size ? " " : "", value_usize); + } + } + + if (units & DN_AgeUnit_Ms) { + DN_Assert((units & DN_AgeUnit_FractionalSec) == 0); + DN_USize value_usize = remainder_ms; + remainder_ms -= value_usize; + if (value_usize || result.size == 0) + DN_FmtAppend(result.data, &result.size, sizeof(result.data), "%s%zums", result.size ? " " : "", value_usize); + } + return result; +} + +DN_API DN_Str8x128 DN_AgeStr8FromSecU64(DN_U64 duration_s, DN_AgeUnit units) +{ + DN_U64 duration_ms = duration_s * 1000; + DN_Str8x128 result = DN_AgeStr8FromMsU64(duration_ms, units); + return result; +} + +DN_API DN_Str8x128 DN_AgeStr8FromSecF64(DN_F64 duration_s, DN_AgeUnit units) +{ + DN_U64 duration_ms = DN_Cast(DN_U64)(duration_s * 1000.0); + DN_Str8x128 result = DN_AgeStr8FromMsU64(duration_ms, units); + return result; +} + +DN_API DN_Str8 DN_Str8FromByteCountType(DN_ByteCountType type) +{ + DN_Str8 result = DN_Str8Lit(""); + switch (type) { + case DN_ByteCountType_B: result = DN_Str8Lit("B"); break; + case DN_ByteCountType_KiB: result = DN_Str8Lit("KiB"); break; + case DN_ByteCountType_MiB: result = DN_Str8Lit("MiB"); break; + case DN_ByteCountType_GiB: result = DN_Str8Lit("GiB"); break; + case DN_ByteCountType_TiB: result = DN_Str8Lit("TiB"); break; + case DN_ByteCountType_Count: result = DN_Str8Lit(""); break; + case DN_ByteCountType_Auto: result = DN_Str8Lit(""); break; + } + return result; +} + +DN_API DN_ByteCountResult DN_ByteCountFromType(DN_U64 bytes, DN_ByteCountType type) +{ + DN_Assert(type != DN_ByteCountType_Count); + DN_ByteCountResult result = {}; + result.bytes = DN_Cast(DN_F64) bytes; + if (type == DN_ByteCountType_Auto) + for (; result.type < DN_ByteCountType_Count && result.bytes >= 1024.0; result.type = DN_Cast(DN_ByteCountType)(DN_Cast(DN_USize) result.type + 1)) + result.bytes /= 1024.0; + else + for (; result.type < type; result.type = DN_Cast(DN_ByteCountType)(DN_Cast(DN_USize) result.type + 1)) + result.bytes /= 1024.0; + result.suffix = DN_Str8FromByteCountType(result.type); + return result; +} + +DN_API DN_Str8x32 DN_ByteCountStr8x32FromType(DN_U64 bytes, DN_ByteCountType type) +{ + DN_ByteCountResult byte_count = DN_ByteCountFromType(bytes, type); + DN_Str8x32 result = DN_Str8x32FromFmt("%.2f%.*s", byte_count.bytes, DN_Str8PrintFmt(byte_count.suffix)); + return result; +} // DN: Single header generator inlined this file => #include "Base/dn_base_containers.cpp" #define DN_CONTAINERS_CPP @@ -787,14 +2893,14 @@ DN_API void *DN_CArray2_InsertArray(void *data, DN_USize *size, DN_USize max, DN DN_USize clamped_index = DN_Min(index, *size); if (clamped_index != *size) { - char const *src = DN_CAST(char *)data + (clamped_index * elem_size); - char const *dest = DN_CAST(char *)data + ((clamped_index + count) * elem_size); - char const *end = DN_CAST(char *)data + (size[0] * elem_size); + char const *src = DN_Cast(char *)data + (clamped_index * elem_size); + char const *dest = DN_Cast(char *)data + ((clamped_index + count) * elem_size); + char const *end = DN_Cast(char *)data + (size[0] * elem_size); DN_USize bytes_to_move = end - src; - DN_Memmove(DN_CAST(void *) dest, src, bytes_to_move); + DN_Memmove(DN_Cast(void *) dest, src, bytes_to_move); } - result = DN_CAST(char *)data + (clamped_index * elem_size); + result = DN_Cast(char *)data + (clamped_index * elem_size); DN_Memcpy(result, items, elem_size * count); *size += count; return result; @@ -843,14 +2949,14 @@ DN_API DN_ArrayEraseResult DN_CArray2_EraseRange(void *data, DN_USize *size, DN_ return result; } -DN_API void *DN_CArray2_MakeArray(void *data, DN_USize *size, DN_USize max, DN_USize data_size, DN_USize make_size, DN_ZeroMem zero_mem) +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) { void *result = nullptr; DN_USize new_size = *size + make_size; if (new_size <= max) { - result = DN_CAST(char *) data + (data_size * size[0]); + result = DN_Cast(char *) data + (data_size * size[0]); *size = new_size; - if (zero_mem == DN_ZeroMem_Yes) + if (z_mem == DN_ZMem_Yes) DN_Memset(result, 0, data_size * make_size); } @@ -859,13 +2965,13 @@ DN_API void *DN_CArray2_MakeArray(void *data, DN_USize *size, DN_USize max, DN_U 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) { - void *result = DN_CArray2_MakeArray(data, size, max, data_size, elems_count, DN_ZeroMem_No); + void *result = DN_CArray2_MakeArray(data, size, max, data_size, elems_count, DN_ZMem_No); if (result) { if (add == DN_ArrayAdd_Append) { DN_Memcpy(result, elems, elems_count * data_size); } else { - char *move_dest = DN_CAST(char *)data + (elems_count * data_size); // Shift elements forward - char *move_src = DN_CAST(char *)data; + char *move_dest = DN_Cast(char *)data + (elems_count * data_size); // Shift elements forward + char *move_src = DN_Cast(char *)data; DN_Memmove(move_dest, move_src, data_size * size[0]); DN_Memcpy(data, elems, data_size * elems_count); } @@ -878,11 +2984,11 @@ DN_API bool DN_CArray2_ResizeFromPool(void **data, DN_USize *size, DN_USize *max bool result = true; if (new_max != *max) { DN_USize bytes_to_alloc = data_size * new_max; - void *buffer = DN_Pool_NewArray(pool, DN_U8, bytes_to_alloc); + void *buffer = DN_PoolNewArray(pool, DN_U8, bytes_to_alloc); if (buffer) { DN_USize bytes_to_copy = data_size * DN_Min(*size, new_max); DN_Memcpy(buffer, *data, bytes_to_copy); - DN_Pool_Dealloc(pool, *data); + DN_PoolDealloc(pool, *data); *data = buffer; *max = new_max; *size = DN_Min(*size, new_max); @@ -1020,7 +3126,7 @@ DN_ArrayEraseResult DN_CArray_EraseRange(T *data, DN_USize *size, DN_USize begin } template -T *DN_CArray_MakeArray(T *data, DN_USize *size, DN_USize max, DN_USize count, DN_ZeroMem zero_mem) +T *DN_CArray_MakeArray(T *data, DN_USize *size, DN_USize max, DN_USize count, DN_ZMem z_mem) { if (!data || !size || count == 0) return nullptr; @@ -1031,7 +3137,7 @@ T *DN_CArray_MakeArray(T *data, DN_USize *size, DN_USize max, DN_USize count, DN // TODO: Use placement new? Why doesn't this work? T *result = data + *size; *size += count; - if (zero_mem == DN_ZeroMem_Yes) + if (z_mem == DN_ZMem_Yes) DN_Memset(result, 0, sizeof(*result) * count); return result; } @@ -1045,11 +3151,11 @@ T *DN_CArray_InsertArray(T *data, DN_USize *size, DN_USize max, DN_USize index, DN_USize clamped_index = DN_Min(index, *size); if (clamped_index != *size) { - char const *src = DN_CAST(char *)(data + clamped_index); - char const *dest = DN_CAST(char *)(data + (clamped_index + count)); - char const *end = DN_CAST(char *)(data + (*size)); + char const *src = DN_Cast(char *)(data + clamped_index); + char const *dest = DN_Cast(char *)(data + (clamped_index + count)); + char const *end = DN_Cast(char *)(data + (*size)); DN_USize bytes_to_move = end - src; - DN_Memmove(DN_CAST(void *) dest, src, bytes_to_move); + DN_Memmove(DN_Cast(void *) dest, src, bytes_to_move); } result = data + clamped_index; @@ -1106,34 +3212,34 @@ DN_ArrayFindResult DN_CArray_Find(T *data, DN_USize size, T const &value) #if !defined(DN_NO_SARRAY) // NOTE: DN_SArray ///////////////////////////////////////////////////////////////////////////////// template -DN_SArray DN_SArray_Init(DN_Arena *arena, DN_USize size, DN_ZeroMem zero_mem) +DN_SArray DN_SArray_Init(DN_Arena *arena, DN_USize size, DN_ZMem z_mem) { DN_SArray result = {}; if (!arena || !size) return result; - result.data = DN_Arena_NewArray(arena, T, size, zero_mem); + result.data = DN_ArenaNewArray(arena, T, size, z_mem); if (result.data) result.max = size; return result; } template -DN_SArray DN_SArray_InitSlice(DN_Arena *arena, DN_Slice slice, DN_USize size, DN_ZeroMem zero_mem) +DN_SArray DN_SArray_InitSlice(DN_Arena *arena, DN_Slice slice, DN_USize size, DN_ZMem z_mem) { DN_USize max = DN_Max(slice.size, size); - DN_SArray result = DN_SArray_Init(arena, max, DN_ZeroMem_No); + DN_SArray result = DN_SArray_Init(arena, max, DN_ZMem_No); if (DN_SArray_IsValid(&result)) { DN_SArray_AddArray(&result, slice.data, slice.size); - if (zero_mem == DN_ZeroMem_Yes) + if (z_mem == DN_ZMem_Yes) DN_Memset(result.data + result.size, 0, (result.max - result.size) * sizeof(T)); } return result; } template -DN_SArray DN_SArray_InitCArray(DN_Arena *arena, T const (&array)[N], DN_USize size, DN_ZeroMem zero_mem) +DN_SArray DN_SArray_InitCArray(DN_Arena *arena, T const (&array)[N], DN_USize size, DN_ZMem z_mem) { - DN_SArray result = DN_SArray_InitSlice(arena, DN_Slice_Init(DN_CAST(T *) array, N), size, zero_mem); + DN_SArray result = DN_SArray_InitSlice(arena, DN_Slice_Init(DN_Cast(T *) array, N), size, z_mem); return result; } @@ -1158,30 +3264,30 @@ DN_Slice DN_SArray_Slice(DN_SArray const *array) { DN_Slice result = {}; if (array) - result = DN_Slice_Init(DN_CAST(T *) array->data, array->size); + result = DN_Slice_Init(DN_Cast(T *) array->data, array->size); return result; } template -T *DN_SArray_MakeArray(DN_SArray *array, DN_USize count, DN_ZeroMem zero_mem) +T *DN_SArray_MakeArray(DN_SArray *array, DN_USize count, DN_ZMem z_mem) { if (!DN_SArray_IsValid(array)) return nullptr; - T *result = DN_CArray_MakeArray(array->data, &array->size, array->max, count, zero_mem); + T *result = DN_CArray_MakeArray(array->data, &array->size, array->max, count, z_mem); return result; } template -T *DN_SArray_Make(DN_SArray *array, DN_ZeroMem zero_mem) +T *DN_SArray_Make(DN_SArray *array, DN_ZMem z_mem) { - T *result = DN_SArray_MakeArray(array, 1, zero_mem); + T *result = DN_SArray_MakeArray(array, 1, z_mem); return result; } template T *DN_SArray_AddArray(DN_SArray *array, T const *items, DN_USize count) { - T *result = DN_SArray_MakeArray(array, count, DN_ZeroMem_No); + T *result = DN_SArray_MakeArray(array, count, DN_ZMem_No); if (result) DN_Memcpy(result, items, count * sizeof(T)); return result; @@ -1294,14 +3400,14 @@ DN_Slice DN_FArray_Slice(DN_FArray const *array) { DN_Slice result = {}; if (array) - result = DN_Slice_Init(DN_CAST(T *) array->data, array->size); + result = DN_Slice_Init(DN_Cast(T *) array->data, array->size); return result; } template T *DN_FArray_AddArray(DN_FArray *array, T const *items, DN_USize count) { - T *result = DN_FArray_MakeArray(array, count, DN_ZeroMem_No); + T *result = DN_FArray_MakeArray(array, count, DN_ZMem_No); if (result) DN_Memcpy(result, items, count * sizeof(T)); return result; @@ -1310,7 +3416,7 @@ 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]) { - T *result = DN_FArray_MakeArray(array, K, DN_ZeroMem_No); + T *result = DN_FArray_MakeArray(array, K, DN_ZMem_No); if (result) DN_Memcpy(result, items, K * sizeof(T)); return result; @@ -1324,18 +3430,18 @@ T *DN_FArray_Add(DN_FArray *array, T const &item) } template -T *DN_FArray_MakeArray(DN_FArray *array, DN_USize count, DN_ZeroMem zero_mem) +T *DN_FArray_MakeArray(DN_FArray *array, DN_USize count, DN_ZMem z_mem) { if (!DN_FArray_IsValid(array)) return nullptr; - T *result = DN_CArray_MakeArray(array->data, &array->size, N, count, zero_mem); + T *result = DN_CArray_MakeArray(array->data, &array->size, N, count, z_mem); return result; } template -T *DN_FArray_Make(DN_FArray *array, DN_ZeroMem zero_mem) +T *DN_FArray_Make(DN_FArray *array, DN_ZMem z_mem) { - T *result = DN_FArray_MakeArray(array, 1, zero_mem); + T *result = DN_FArray_MakeArray(array, 1, z_mem); return result; } @@ -1417,7 +3523,7 @@ DN_Slice DN_Slice_Init(T *const data, DN_USize size) template DN_Slice DN_Slice_InitCArrayCopy(DN_Arena *arena, T const (&array)[N]) { - DN_Slice result = DN_Slice_Alloc(arena, N, DN_ZeroMem_No); + DN_Slice result = DN_Slice_Alloc(arena, N, DN_ZMem_No); if (result.data) DN_Memcpy(result.data, array, sizeof(T) * N); return result; @@ -1426,7 +3532,7 @@ DN_Slice DN_Slice_InitCArrayCopy(DN_Arena *arena, T const (&array)[N]) template DN_Slice DN_Slice_CopyPtr(DN_Arena *arena, T *const data, DN_USize size) { - T *copy = DN_Arena_NewArrayCopy(arena, T, data, size); + T *copy = DN_ArenaNewArrayCopy(arena, T, data, size); DN_Slice result = DN_Slice_Init(copy, copy ? size : 0); return result; } @@ -1439,12 +3545,12 @@ DN_Slice DN_Slice_Copy(DN_Arena *arena, DN_Slice slice) } template -DN_Slice DN_Slice_Alloc(DN_Arena *arena, DN_USize size, DN_ZeroMem zero_mem) +DN_Slice DN_Slice_Alloc(DN_Arena *arena, DN_USize size, DN_ZMem z_mem) { DN_Slice result = {}; if (!arena || size == 0) return result; - result.data = DN_Arena_NewArray(arena, T, size, zero_mem); + result.data = DN_ArenaNewArray(arena, T, size, z_mem); if (result.data) result.size = size; return result; @@ -1468,9 +3574,9 @@ DN_DSMap DN_DSMap_Init(DN_Arena *arena, DN_U32 size, DN_DSMapFlags flags) if (!DN_Check(arena)) return result; result.arena = arena; - result.pool = DN_Pool_FromArena(arena, DN_POOL_DEFAULT_ALIGN); - result.hash_to_slot = DN_Arena_NewArray(result.arena, DN_U32, size, DN_ZeroMem_Yes); - result.slots = DN_Arena_NewArray(result.arena, DN_DSMapSlot, size, DN_ZeroMem_Yes); + result.pool = DN_PoolFromArena(arena, DN_POOL_DEFAULT_ALIGN); + result.hash_to_slot = DN_ArenaNewArray(result.arena, DN_U32, size, DN_ZMem_Yes); + result.slots = DN_ArenaNewArray(result.arena, DN_DSMapSlot, size, DN_ZMem_Yes); result.occupied = 1; // For sentinel result.size = size; result.initial_size = size; @@ -1480,13 +3586,13 @@ DN_DSMap DN_DSMap_Init(DN_Arena *arena, DN_U32 size, DN_DSMapFlags flags) } template -void DN_DSMap_Deinit(DN_DSMap *map, DN_ZeroMem zero_mem) +void DN_DSMap_Deinit(DN_DSMap *map, DN_ZMem z_mem) { if (!map) return; - // TODO(doyle): Use zero_mem - (void)zero_mem; - DN_Arena_Deinit(map->arena); + // TODO(doyle): Use z_mem + (void)z_mem; + DN_ArenaDeinit(map->arena); *map = {}; } @@ -1510,7 +3616,7 @@ DN_U32 DN_DSMap_Hash(DN_DSMap const *map, DN_DSMapKey key) return result; if (key.type == DN_DSMapKeyType_U64NoHash) { - result = DN_CAST(DN_U32) key.u64; + result = DN_Cast(DN_U32) key.u64; return result; } @@ -1538,12 +3644,12 @@ DN_U32 DN_DSMap_Hash(DN_DSMap const *map, DN_DSMapKey key) case DN_DSMapKeyType_Invalid: break; case DN_DSMapKeyType_Buffer: - key_ptr = DN_CAST(char const *) key.buffer_data; + key_ptr = DN_Cast(char const *) key.buffer_data; len = key.buffer_size; break; case DN_DSMapKeyType_U64: - key_ptr = DN_CAST(char const *) & key.u64; + key_ptr = DN_Cast(char const *) & key.u64; len = sizeof(key.u64); break; } @@ -1647,7 +3753,7 @@ DN_DSMapResult DN_DSMap_Make(DN_DSMap *map, DN_DSMapKey key) if ((key.type == DN_DSMapKeyType_Buffer || key.type == DN_DSMapKeyType_BufferAsU64NoHash) && !key.no_copy_buffer) - result.slot->key.buffer_data = DN_Pool_NewArrayCopy(&map->pool, char, key.buffer_data, key.buffer_size); + result.slot->key.buffer_data = DN_PoolNewArrayCopy(&map->pool, char, key.buffer_data, key.buffer_size); } } else { result.slot = map->slots + map->hash_to_slot[index]; @@ -1747,7 +3853,7 @@ bool DN_DSMap_Resize(DN_DSMap *map, DN_U32 size) } if ((map->flags & DN_DSMapFlags_DontFreeArenaOnResize) == 0) - DN_DSMap_Deinit(map, DN_ZeroMem_No); + DN_DSMap_Deinit(map, DN_ZMem_No); *map = new_map; // Update the map inplace map->arena = prev_arena; // Restore the previous arena pointer, it's been de-init-ed *map->arena = new_arena; // Re-init the old arena with the new data @@ -1774,7 +3880,7 @@ bool DN_DSMap_Erase(DN_DSMap *map, DN_DSMapKey key) DN_DSMapSlot *slot = map->slots + slot_index; if (!slot->key.no_copy_buffer) - DN_Pool_Dealloc(&map->pool, DN_CAST(void *) slot->key.buffer_data); + DN_PoolDealloc(&map->pool, DN_Cast(void *) slot->key.buffer_data); *slot = {}; // TODO: Optional? if (map->occupied > 1 /*Sentinel*/) { @@ -1851,7 +3957,7 @@ DN_DSMapKey DN_DSMap_KeyBuffer(DN_DSMap const *map, void const *data, DN_USiz DN_DSMapKey result = {}; result.type = DN_DSMapKeyType_Buffer; result.buffer_data = data; - result.buffer_size = DN_CAST(DN_U32) size; + result.buffer_size = DN_Cast(DN_U32) size; result.hash = DN_DSMap_Hash(map, result); return result; } @@ -1862,7 +3968,7 @@ DN_DSMapKey DN_DSMap_KeyBufferAsU64NoHash(DN_DSMap const *map, void const *da DN_DSMapKey result = {}; result.type = DN_DSMapKeyType_BufferAsU64NoHash; result.buffer_data = data; - result.buffer_size = DN_CAST(DN_U32) size; + result.buffer_size = DN_Cast(DN_U32) size; DN_Assert(size >= sizeof(result.hash)); DN_Memcpy(&result.hash, data, sizeof(result.hash)); return result; @@ -1935,16 +4041,16 @@ DN_API bool DN_List_AttachTail_(DN_List *list, DN_ListChunk *tail) template DN_API DN_ListChunk *DN_List_AllocArena_(DN_List *list, DN_Arena *arena, DN_USize count) { - auto *result = DN_Arena_New(arena, DN_ListChunk, DN_ZeroMem_Yes); - DN_ArenaTempMem tmem = DN_Arena_TempMemBegin(arena); + auto *result = DN_ArenaNew(arena, DN_ListChunk, DN_ZMem_Yes); + DN_ArenaTempMem tmem = DN_ArenaTempMemBegin(arena); if (!result) return nullptr; DN_USize items = DN_Max(list->chunk_size, count); - result->data = DN_Arena_NewArray(arena, T, items, DN_ZeroMem_Yes); + result->data = DN_ArenaNewArray(arena, T, items, DN_ZMem_Yes); result->size = items; if (!result->data) { - DN_Arena_TempMemEnd(tmem); + DN_ArenaTempMemEnd(tmem); result = nullptr; } @@ -1955,15 +4061,15 @@ DN_API DN_ListChunk *DN_List_AllocArena_(DN_List *list, DN_Arena *arena, D template DN_API DN_ListChunk *DN_List_AllocPool_(DN_List *list, DN_Pool *pool, DN_USize count) { - auto *result = DN_Pool_New(pool, DN_ListChunk); + auto *result = DN_PoolNew(pool, DN_ListChunk); if (!result) return nullptr; DN_USize items = DN_Max(list->chunk_size, count); - result->data = DN_Pool_NewArray(pool, T, items); + result->data = DN_PoolNewArray(pool, T, items); result->size = items; if (!result->data) { - DN_Pool_Dealloc(result); + DN_PoolDealloc(result); result = nullptr; } @@ -2126,12 +4232,12 @@ template DN_Slice DN_List_ToSliceCopy(DN_List const *list, DN_Arena *arena) { // TODO(doyle): Chunk memcopies is much faster - DN_Slice result = DN_Slice_Alloc(arena, list->count, DN_ZeroMem_No); + DN_Slice result = DN_Slice_Alloc(arena, list->count, DN_ZMem_No); if (result.size) { DN_USize slice_index = 0; DN_MSVC_WARNING_PUSH DN_MSVC_WARNING_DISABLE(6011) // Dereferencing NULL pointer 'x' - for (DN_ListIterator it = {}; DN_List_Iterate(DN_CAST(DN_List *) list, &it, 0);) + for (DN_ListIterator it = {}; DN_List_Iterate(DN_Cast(DN_List *) list, &it, 0);) result.data[slice_index++] = *it.data; DN_MSVC_WARNING_POP DN_Assert(slice_index == result.size); @@ -2155,7 +4261,7 @@ DN_API DN_Str8 DN_Slice_Str8Render(DN_Arena *arena, DN_Slice array, DN_ total_size += item.size; } - result = DN_Str8_Alloc(arena, total_size, DN_ZeroMem_No); + result = DN_Str8FromArena(arena, total_size, DN_ZMem_No); if (result.data) { DN_USize write_index = 0; for (DN_USize index = 0; index < array.size; index++) { @@ -2174,7 +4280,7 @@ DN_API DN_Str8 DN_Slice_Str8Render(DN_Arena *arena, DN_Slice array, DN_ DN_API DN_Str8 DN_Slice_Str8RenderSpaceSeparated(DN_Arena *arena, DN_Slice array) { - DN_Str8 result = DN_Slice_Str8Render(arena, array, DN_STR8(" ")); + DN_Str8 result = DN_Slice_Str8Render(arena, array, DN_Str8Lit(" ")); return result; } @@ -2192,7 +4298,7 @@ DN_API DN_Str16 DN_Slice_Str16Render(DN_Arena *arena, DN_Slice array, total_size += item.size; } - result = {DN_Arena_NewArray(arena, wchar_t, total_size + 1, DN_ZeroMem_No), total_size}; + result = {DN_ArenaNewArray(arena, wchar_t, total_size + 1, DN_ZMem_No), total_size}; if (result.data) { DN_USize write_index = 0; for (DN_USize index = 0; index < array.size; index++) { @@ -2212,7 +4318,7 @@ DN_API DN_Str16 DN_Slice_Str16Render(DN_Arena *arena, DN_Slice array, DN_API DN_Str16 DN_Slice_Str16RenderSpaceSeparated(DN_Arena *arena, DN_Slice array) { - DN_Str16 result = DN_Slice_Str16Render(arena, array, DN_STR16(L" ")); + DN_Str16 result = DN_Slice_Str16Render(arena, array, DN_Str16Lit(L" ")); return result; } @@ -2223,7 +4329,7 @@ DN_API DN_DSMapKey DN_DSMap_KeyU64NoHash(DN_U64 u64) DN_DSMapKey result = {}; result.type = DN_DSMapKeyType_U64NoHash; result.u64 = u64; - result.hash = DN_CAST(DN_U32) u64; + result.hash = DN_Cast(DN_U32) u64; return result; } @@ -2252,2148 +4358,6 @@ DN_API bool operator==(DN_DSMapKey lhs, DN_DSMapKey rhs) return result; } #endif // !defined(DN_NO_DSMAP) -// DN: Single header generator inlined this file => #include "Base/dn_base_convert.cpp" -#define DN_CONVERT_CPP - -// DN: Single header generator commented out this header => #include "../dn_base_inc.h" - -DN_API DN_NibbleFromU8Result DN_CVT_NibbleFromU8(DN_U8 u8) -{ - static char const *table = "0123456789abcdef"; - DN_U8 lhs = (u8 >> 0) & 0xF; - DN_U8 rhs = (u8 >> 4) & 0xF; - DN_NibbleFromU8Result result = {}; - result.nibble0 = table[rhs]; - result.nibble1 = table[lhs]; - return result; -} - -DN_API DN_U8 DN_CVT_U8FromHexNibble(char hex) -{ - bool digit = hex >= '0' && hex <= '9'; - bool upper = hex >= 'A' && hex <= 'F'; - bool lower = hex >= 'a' && hex <= 'f'; - DN_U8 result = 0xFF; - if (digit) - result = hex - '0'; - if (upper) - result = hex - 'A' + 10; - if (lower) - result = hex - 'a' + 10; - return result; -} - -DN_API int DN_CVT_FmtBuffer3DotTruncate(char *buffer, int size, DN_FMT_ATTRIB char const *fmt, ...) -{ - va_list args; - va_start(args, fmt); - int size_required = DN_VSNPrintF(buffer, size, fmt, args); - int result = DN_Max(DN_Min(size_required, size - 1), 0); - if (result == size - 1) { - buffer[size - 2] = '.'; - buffer[size - 3] = '.'; - } - va_end(args); - return result; -} - -DN_API DN_CVTU64Str8 DN_CVT_Str8FromU64(DN_U64 val, char separator) -{ - DN_CVTU64Str8 result = {}; - if (val == 0) { - result.data[result.size++] = '0'; - } else { - // NOTE: The number is written in reverse because we form the string by - // dividing by 10, so we write it in, then reverse it out after all is - // done. - DN_CVTU64Str8 temp = {}; - for (DN_USize digit_count = 0; val > 0; digit_count++) { - if (separator && (digit_count != 0) && (digit_count % 3 == 0)) - temp.data[temp.size++] = separator; - - auto digit = DN_CAST(char)(val % 10); - temp.data[temp.size++] = '0' + digit; - val /= 10; - } - - // NOTE: Reverse the string - DN_MSVC_WARNING_PUSH - DN_MSVC_WARNING_DISABLE(6293) // Ill-defined for-loop - DN_MSVC_WARNING_DISABLE(6385) // Reading invalid data from 'temp.data' unsigned overflow is valid for loop termination - for (DN_USize temp_index = temp.size - 1; temp_index < temp.size; temp_index--) { - char ch = temp.data[temp_index]; - result.data[result.size++] = ch; - } - DN_MSVC_WARNING_POP - } - - return result; -} - -DN_API DN_CVTU64Bytes DN_CVT_BytesFromU64(DN_U64 bytes, DN_CVTBytesType type) -{ - DN_Assert(type != DN_CVTBytesType_Count); - DN_CVTU64Bytes result = {}; - result.bytes = DN_CAST(DN_F64) bytes; - - if (type == DN_CVTBytesType_Auto) - for (; result.type < DN_CVTBytesType_Count && result.bytes >= 1024.0; result.type = DN_CAST(DN_CVTBytesType)(DN_CAST(DN_USize) result.type + 1)) - result.bytes /= 1024.0; - else - for (; result.type < type; result.type = DN_CAST(DN_CVTBytesType)(DN_CAST(DN_USize) result.type + 1)) - result.bytes /= 1024.0; - - result.suffix = DN_CVT_BytesTypeToStr8(result.type); - return result; -} - -DN_API DN_Str8 DN_CVT_BytesStr8FromU64(DN_Arena *arena, DN_U64 bytes, DN_CVTBytesType desired_type) -{ - DN_CVTU64Bytes byte_size = DN_CVT_BytesFromU64(bytes, desired_type); - DN_Str8 result = DN_Str8_FromF(arena, "%.2f%.*s", byte_size.bytes, DN_STR_FMT(byte_size.suffix)); - return result; -} - -DN_API DN_Str8 DN_CVT_BytesTypeToStr8(DN_CVTBytesType type) -{ - DN_Str8 result = DN_STR8(""); - switch (type) { - case DN_CVTBytesType_B: result = DN_STR8("B"); break; - case DN_CVTBytesType_KiB: result = DN_STR8("KiB"); break; - case DN_CVTBytesType_MiB: result = DN_STR8("MiB"); break; - case DN_CVTBytesType_GiB: result = DN_STR8("GiB"); break; - case DN_CVTBytesType_TiB: result = DN_STR8("TiB"); break; - case DN_CVTBytesType_Count: result = DN_STR8(""); break; - case DN_CVTBytesType_Auto: result = DN_STR8(""); break; - } - return result; -} - -DN_API DN_Str8 DN_CVT_AgeFromU64(DN_Arena *arena, DN_U64 age_s, DN_CVTU64AgeUnit unit) -{ - DN_Str8 result = {}; - if (!arena) - return result; - - char buffer[512]; - DN_Arena stack_arena = DN_Arena_FromBuffer(buffer, sizeof(buffer), DN_ArenaFlags_NoPoison); - DN_Str8Builder builder = DN_Str8Builder_FromArena(&stack_arena); - DN_U64 remainder = age_s; - - if (unit & DN_CVTU64AgeUnit_Year) { - DN_USize value = remainder / DN_YearsToSec(1); - remainder -= DN_YearsToSec(value); - if (value) - DN_Str8Builder_AppendF(&builder, "%s%zuyr", builder.string_size ? " " : "", value); - } - - if (unit & DN_CVTU64AgeUnit_Week) { - DN_USize value = remainder / DN_WeeksToSec(1); - remainder -= DN_WeeksToSec(value); - if (value) - DN_Str8Builder_AppendF(&builder, "%s%zuw", builder.string_size ? " " : "", value); - } - - if (unit & DN_CVTU64AgeUnit_Day) { - DN_USize value = remainder / DN_DaysToSec(1); - remainder -= DN_DaysToSec(value); - if (value) - DN_Str8Builder_AppendF(&builder, "%s%zud", builder.string_size ? " " : "", value); - } - - if (unit & DN_CVTU64AgeUnit_Hr) { - DN_USize value = remainder / DN_HoursToSec(1); - remainder -= DN_HoursToSec(value); - if (value) - DN_Str8Builder_AppendF(&builder, "%s%zuh", builder.string_size ? " " : "", value); - } - - if (unit & DN_CVTU64AgeUnit_Min) { - DN_USize value = remainder / DN_MinutesToSec(1); - remainder -= DN_MinutesToSec(value); - if (value) - DN_Str8Builder_AppendF(&builder, "%s%zum", builder.string_size ? " " : "", value); - } - - if (unit & DN_CVTU64AgeUnit_Sec) { - DN_USize value = remainder; - if (value || builder.string_size == 0) - DN_Str8Builder_AppendF(&builder, "%s%zus", builder.string_size ? " " : "", value); - } - - result = DN_Str8Builder_Build(&builder, arena); - return result; -} - -DN_API DN_Str8 DN_CVT_AgeFromF64(DN_Arena *arena, DN_F64 age_s, DN_CVTU64AgeUnit unit) -{ - DN_Str8 result = {}; - if (!arena) - return result; - - char buffer[256]; - DN_Arena stack_arena = DN_Arena_FromBuffer(buffer, sizeof(buffer), DN_ArenaFlags_NoPoison); - DN_Str8Builder builder = DN_Str8Builder_FromArena(&stack_arena); - DN_F64 remainder = age_s; - - if (unit & DN_CVTU64AgeUnit_Year) { - DN_F64 value = remainder / DN_CAST(DN_F64) DN_YearsToSec(1); - if (value >= 1.0) { - remainder -= DN_YearsToSec(value); - DN_Str8Builder_AppendF(&builder, "%s%.1fyr", builder.string_size ? " " : "", value); - } - } - - if (unit & DN_CVTU64AgeUnit_Week) { - DN_F64 value = remainder / DN_CAST(DN_F64) DN_WeeksToSec(1); - if (value >= 1.0) { - remainder -= DN_WeeksToSec(value); - DN_Str8Builder_AppendF(&builder, "%s%.1fw", builder.string_size ? " " : "", value); - } - } - - if (unit & DN_CVTU64AgeUnit_Day) { - DN_F64 value = remainder / DN_CAST(DN_F64) DN_DaysToSec(1); - if (value >= 1.0) { - remainder -= DN_WeeksToSec(value); - DN_Str8Builder_AppendF(&builder, "%s%.1fd", builder.string_size ? " " : "", value); - } - } - - if (unit & DN_CVTU64AgeUnit_Hr) { - DN_F64 value = remainder / DN_CAST(DN_F64) DN_HoursToSec(1); - if (value >= 1.0) { - remainder -= DN_HoursToSec(value); - DN_Str8Builder_AppendF(&builder, "%s%.1fh", builder.string_size ? " " : "", value); - } - } - - if (unit & DN_CVTU64AgeUnit_Min) { - DN_F64 value = remainder / DN_CAST(DN_F64) DN_MinutesToSec(1); - if (value >= 1.0) { - remainder -= DN_MinutesToSec(value); - DN_Str8Builder_AppendF(&builder, "%s%.1fm", builder.string_size ? " " : "", value); - } - } - - if (unit & DN_CVTU64AgeUnit_Sec) { - DN_F64 value = remainder; - DN_Str8Builder_AppendF(&builder, "%s%.1fs", builder.string_size ? " " : "", value); - } - - result = DN_Str8Builder_Build(&builder, arena); - return result; -} - -DN_API DN_U64 DN_CVT_U64FromHex(DN_Str8 hex) -{ - DN_Str8 real_hex = DN_Str8_TrimPrefix(DN_Str8_TrimPrefix(hex, DN_STR8("0x")), DN_STR8("0X")); - DN_USize max_hex_size = sizeof(DN_U64) * 2 /*hex chars per byte*/; - DN_Assert(real_hex.size <= max_hex_size); - - DN_USize size = DN_Min(max_hex_size, real_hex.size); - DN_U64 result = 0; - for (DN_USize index = 0; index < size; index++) { - char ch = real_hex.data[index]; - DN_U8 val = DN_CVT_U8FromHexNibble(ch); - if (val == 0xFF) - break; - result = (result << 4) | val; - } - return result; -} - -DN_API DN_Str8 DN_CVT_HexFromU64(DN_Arena *arena, DN_U64 number, uint32_t flags) -{ - DN_Str8 prefix = {}; - if ((flags & DN_CVTU64HexStrFlags_0xPrefix)) - prefix = DN_STR8("0x"); - - char const *fmt = (flags & DN_CVTU64HexStrFlags_UppercaseHex) ? "%I64X" : "%I64x"; - DN_USize required_size = DN_CStr8_FSize(fmt, number) + prefix.size; - DN_Str8 result = DN_Str8_Alloc(arena, required_size, DN_ZeroMem_No); - - if (DN_Str8_HasData(result)) { - DN_Memcpy(result.data, prefix.data, prefix.size); - int space = DN_CAST(int) DN_Max((result.size - prefix.size) + 1, 0); /*null-terminator*/ - DN_SNPrintF(result.data + prefix.size, space, fmt, number); - } - return result; -} - -DN_API DN_CVTU64HexStr DN_CVT_HexFromU64Str8(DN_U64 number, DN_CVTU64HexStrFlags flags) -{ - DN_Str8 prefix = {}; - if (flags & DN_CVTU64HexStrFlags_0xPrefix) - prefix = DN_STR8("0x"); - - DN_CVTU64HexStr result = {}; - DN_Memcpy(result.data, prefix.data, prefix.size); - result.size += DN_CAST(int8_t) prefix.size; - - char const *fmt = (flags & DN_CVTU64HexStrFlags_UppercaseHex) ? "%I64X" : "%I64x"; - int size = DN_SNPrintF(result.data + result.size, DN_ArrayCountU(result.data) - result.size, fmt, number); - result.size += DN_CAST(uint8_t) size; - DN_Assert(result.size < DN_ArrayCountU(result.data)); - - // NOTE: snprintf returns the required size of the format string - // irrespective of if there's space or not, but, always null terminates so - // the last byte is wasted. - result.size = DN_Min(result.size, DN_ArrayCountU(result.data) - 1); - return result; -} - -DN_API bool DN_CVT_HexFromBytesPtr(void const *src, DN_USize src_size, char *dest, DN_USize dest_size) -{ - if (!src || !dest) - return false; - - if (!DN_Check(dest_size >= src_size * 2)) - return false; - - char const *HEX = "0123456789abcdef"; - unsigned char const *src_u8 = DN_CAST(unsigned char const *) src; - for (DN_USize src_index = 0, dest_index = 0; src_index < src_size; src_index++) { - char byte = src_u8[src_index]; - char hex01 = (byte >> 4) & 0b1111; - char hex02 = (byte >> 0) & 0b1111; - dest[dest_index++] = HEX[(int)hex01]; - dest[dest_index++] = HEX[(int)hex02]; - } - - return true; -} - -DN_API DN_Str8 DN_CVT_HexFromBytes(DN_Arena *arena, void const *src, DN_USize size) -{ - DN_Str8 result = {}; - if (!src || size <= 0) - return result; - - result = DN_Str8_Alloc(arena, size * 2, DN_ZeroMem_No); - result.data[result.size] = 0; - bool converted = DN_CVT_HexFromBytesPtr(src, size, result.data, result.size); - DN_Assert(converted); - return result; -} - -DN_API DN_USize DN_CVT_BytesFromHexPtrUnchecked(DN_Str8 hex, void *dest, DN_USize dest_size) -{ - DN_USize result = 0; - unsigned char *dest_u8 = DN_CAST(unsigned char *) dest; - - for (DN_USize hex_index = 0; hex_index < hex.size; hex_index += 2, result += 1) { - char hex01 = hex.data[hex_index]; - char hex02 = (hex_index + 1 < hex.size) ? hex.data[hex_index + 1] : 0; - char bit4_01 = DN_CVT_U8FromHexNibble(hex01); - char bit4_02 = DN_CVT_U8FromHexNibble(hex02); - char byte = (bit4_01 << 4) | (bit4_02 << 0); - dest_u8[result] = byte; - } - - DN_Assert(result <= dest_size); - return result; -} - -DN_API DN_USize DN_CVT_BytesFromHexPtr(DN_Str8 hex, void *dest, DN_USize dest_size) -{ - hex = DN_Str8_TrimPrefix(hex, DN_STR8("0x")); - hex = DN_Str8_TrimPrefix(hex, DN_STR8("0X")); - - DN_USize result = 0; - if (!DN_Str8_HasData(hex)) - return result; - - // NOTE: Trimmed hex can be "0xf" -> "f" or "0xAB" -> "AB" - // Either way, the size can be odd or even, hence we round up to the nearest - // multiple of two to ensure that we calculate the min buffer size orrectly. - DN_USize hex_size_rounded_up = hex.size + (hex.size % 2); - DN_USize min_buffer_size = hex_size_rounded_up / 2; - if (hex.size <= 0 || !DN_Check(dest_size >= min_buffer_size)) - return result; - - result = DN_CVT_BytesFromHexPtrUnchecked(hex, dest, dest_size); - return result; -} - -DN_API DN_Str8 DN_CVT_BytesFromHexUnchecked(DN_Arena *arena, DN_Str8 hex) -{ - DN_USize hex_size_rounded_up = hex.size + (hex.size % 2); - DN_Str8 result = DN_Str8_Alloc(arena, (hex_size_rounded_up / 2), DN_ZeroMem_No); - if (result.data) { - DN_USize bytes_written = DN_CVT_BytesFromHexPtr(hex, result.data, result.size); - DN_Assert(bytes_written == result.size); - } - return result; -} - -DN_API DN_Str8 DN_CVT_BytesFromHex(DN_Arena *arena, DN_Str8 hex) -{ - hex = DN_Str8_TrimPrefix(hex, DN_STR8("0x")); - hex = DN_Str8_TrimPrefix(hex, DN_STR8("0X")); - - DN_Str8 result = {}; - if (!DN_Str8_HasData(hex)) - return result; - - if (!DN_Check(DN_Str8_IsAll(hex, DN_Str8IsAll_Hex))) - return result; - - result = DN_CVT_BytesFromHexUnchecked(arena, hex); - return result; -} -// DN: Single header generator inlined this file => #include "Base/dn_base_mem.cpp" -#define DN_BASE_MEM_CPP - -// DN: Single header generator commented out this header => #include "../dn_base_inc.h" - -static DN_ArenaBlock *DN_Arena_BlockFromMemFuncs_(DN_U64 reserve, DN_U64 commit, bool track_alloc, bool alloc_can_leak, DN_ArenaMemFuncs mem_funcs) -{ - DN_ArenaBlock *result = nullptr; - switch (mem_funcs.type) { - case DN_ArenaMemFuncType_Nil: - break; - - case DN_ArenaMemFuncType_Basic: { - DN_AssertF(reserve > DN_ARENA_HEADER_SIZE, "%I64u > %I64u", reserve, DN_ARENA_HEADER_SIZE); - result = DN_CAST(DN_ArenaBlock *) mem_funcs.basic_alloc(reserve); - if (!result) - return result; - - result->used = DN_ARENA_HEADER_SIZE; - result->commit = reserve; - result->reserve = reserve; - } break; - - case DN_ArenaMemFuncType_VMem: { - DN_AssertF(mem_funcs.vmem_page_size, "Page size must be set to a non-zero, power of two value"); - DN_Assert(DN_IsPowerOfTwo(mem_funcs.vmem_page_size)); - - DN_USize const page_size = mem_funcs.vmem_page_size; - DN_U64 real_reserve = reserve ? reserve : DN_ARENA_RESERVE_SIZE; - DN_U64 real_commit = commit ? commit : DN_ARENA_COMMIT_SIZE; - real_reserve = DN_AlignUpPowerOfTwo(real_reserve, page_size); - real_commit = DN_Min(DN_AlignUpPowerOfTwo(real_commit, page_size), real_reserve); - DN_AssertF(DN_ARENA_HEADER_SIZE < real_commit && real_commit <= real_reserve, "%I64u < %I64u <= %I64u", DN_ARENA_HEADER_SIZE, real_commit, real_reserve); - - DN_MemCommit mem_commit = real_reserve == real_commit ? DN_MemCommit_Yes : DN_MemCommit_No; - result = DN_CAST(DN_ArenaBlock *) mem_funcs.vmem_reserve(real_reserve, mem_commit, DN_MemPage_ReadWrite); - if (!result) - return result; - - if (mem_commit == DN_MemCommit_No && !mem_funcs.vmem_commit(result, real_commit, DN_MemPage_ReadWrite)) { - mem_funcs.vmem_release(result, real_reserve); - return result; - } - - result->used = DN_ARENA_HEADER_SIZE; - result->commit = real_commit; - result->reserve = real_reserve; - } break; - } - - if (track_alloc && result) - DN_DBGTrackAlloc(result, result->reserve, alloc_can_leak); - - return result; -} - -static DN_ArenaBlock *DN_Arena_BlockFlagsFromMemFuncs_(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs) -{ - bool track_alloc = (flags & DN_ArenaFlags_NoAllocTrack) == 0; - bool alloc_can_leak = flags & DN_ArenaFlags_AllocCanLeak; - DN_ArenaBlock *result = DN_Arena_BlockFromMemFuncs_(reserve, commit, track_alloc, alloc_can_leak, mem_funcs); - if (result && ((flags & DN_ArenaFlags_NoPoison) == 0)) - DN_ASanPoisonMemoryRegion(DN_CAST(char *) result + DN_ARENA_HEADER_SIZE, result->commit - DN_ARENA_HEADER_SIZE); - return result; -} - -static void DN_Arena_UpdateStatsOnNewBlock_(DN_Arena *arena, DN_ArenaBlock const *block) -{ - DN_Assert(arena); - if (block) { - arena->stats.info.used += block->used; - arena->stats.info.commit += block->commit; - arena->stats.info.reserve += block->reserve; - arena->stats.info.blocks += 1; - - arena->stats.hwm.used = DN_Max(arena->stats.hwm.used, arena->stats.info.used); - arena->stats.hwm.commit = DN_Max(arena->stats.hwm.commit, arena->stats.info.commit); - arena->stats.hwm.reserve = DN_Max(arena->stats.hwm.reserve, arena->stats.info.reserve); - arena->stats.hwm.blocks = DN_Max(arena->stats.hwm.blocks, arena->stats.info.blocks); - } -} - -DN_API DN_Arena DN_Arena_FromBuffer(void *buffer, DN_USize size, DN_ArenaFlags flags) -{ - DN_Assert(buffer); - DN_AssertF(DN_ARENA_HEADER_SIZE < size, "Buffer (%zu bytes) too small, need atleast %zu bytes to store arena metadata", size, DN_ARENA_HEADER_SIZE); - DN_AssertF(DN_IsPowerOfTwo(size), "Buffer (%zu bytes) must be a power-of-two", size); - - // NOTE: Init block - DN_ArenaBlock *block = DN_CAST(DN_ArenaBlock *) buffer; - block->commit = size; - block->reserve = size; - block->used = DN_ARENA_HEADER_SIZE; - if (block && ((flags & DN_ArenaFlags_NoPoison) == 0)) - DN_ASanPoisonMemoryRegion(DN_CAST(char *) block + DN_ARENA_HEADER_SIZE, block->commit - DN_ARENA_HEADER_SIZE); - - DN_Arena result = {}; - result.flags = flags | DN_ArenaFlags_NoGrow | DN_ArenaFlags_NoAllocTrack | DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_UserBuffer; - result.curr = block; - DN_Arena_UpdateStatsOnNewBlock_(&result, result.curr); - return result; -} - -DN_API DN_Arena DN_Arena_FromMemFuncs(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs) -{ - DN_Arena result = {}; - result.flags = flags; - result.mem_funcs = mem_funcs; - result.flags |= DN_ArenaFlags_MemFuncs; - result.curr = DN_Arena_BlockFlagsFromMemFuncs_(reserve, commit, flags, mem_funcs); - DN_Arena_UpdateStatsOnNewBlock_(&result, result.curr); - return result; -} - -static void DN_Arena_BlockDeinit_(DN_Arena const *arena, DN_ArenaBlock *block) -{ - DN_USize release_size = block->reserve; - if (DN_BitIsNotSet(arena->flags, DN_ArenaFlags_NoAllocTrack)) - DN_DBGTrackDealloc(block); - DN_ASanUnpoisonMemoryRegion(block, block->commit); - if (arena->flags & DN_ArenaFlags_MemFuncs) { - if (arena->mem_funcs.type == DN_ArenaMemFuncType_Basic) - arena->mem_funcs.basic_dealloc(block); - else - arena->mem_funcs.vmem_release(block, release_size); - } -} - -DN_API void DN_Arena_Deinit(DN_Arena *arena) -{ - for (DN_ArenaBlock *block = arena ? arena->curr : nullptr; block;) { - DN_ArenaBlock *block_to_free = block; - block = block->prev; - DN_Arena_BlockDeinit_(arena, block_to_free); - } - if (arena) - *arena = {}; -} - -DN_API bool DN_Arena_CommitTo(DN_Arena *arena, DN_U64 pos) -{ - if (!arena || !arena->curr) - return false; - - DN_ArenaBlock *curr = arena->curr; - if (pos <= curr->commit) - return true; - - DN_U64 real_pos = pos; - if (!DN_Check(pos <= curr->reserve)) - real_pos = curr->reserve; - - DN_Assert(arena->mem_funcs.vmem_page_size); - DN_USize end_commit = DN_AlignUpPowerOfTwo(real_pos, arena->mem_funcs.vmem_page_size); - DN_USize commit_size = end_commit - curr->commit; - char *commit_ptr = DN_CAST(char *) curr + curr->commit; - if (!arena->mem_funcs.vmem_commit(commit_ptr, commit_size, DN_MemPage_ReadWrite)) - return false; - - bool poison = DN_ASAN_POISON && ((arena->flags & DN_ArenaFlags_NoPoison) == 0); - if (poison) - DN_ASanPoisonMemoryRegion(commit_ptr, commit_size); - - curr->commit = end_commit; - return true; -} - -DN_API bool DN_Arena_Commit(DN_Arena *arena, DN_U64 size) -{ - if (!arena || !arena->curr) - return false; - DN_U64 pos = DN_Min(arena->curr->reserve, arena->curr->commit + size); - bool result = DN_Arena_CommitTo(arena, pos); - return result; -} - -DN_API bool DN_Arena_Grow(DN_Arena *arena, DN_U64 reserve, DN_U64 commit) -{ - if (arena->flags & (DN_ArenaFlags_NoGrow | DN_ArenaFlags_UserBuffer)) - return false; - - bool result = false; - DN_ArenaBlock *new_block = DN_Arena_BlockFlagsFromMemFuncs_(reserve, commit, arena->flags, arena->mem_funcs); - if (new_block) { - result = true; - new_block->prev = arena->curr; - arena->curr = new_block; - new_block->reserve_sum = new_block->prev->reserve_sum + new_block->prev->reserve; - DN_Arena_UpdateStatsOnNewBlock_(arena, arena->curr); - } - return result; -} - -DN_API void *DN_Arena_Alloc(DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZeroMem zero_mem) -{ - if (!arena) - return nullptr; - - if (!arena->curr) { - arena->curr = DN_Arena_BlockFlagsFromMemFuncs_(DN_ARENA_RESERVE_SIZE, DN_ARENA_COMMIT_SIZE, arena->flags, arena->mem_funcs); - DN_Arena_UpdateStatsOnNewBlock_(arena, arena->curr); - } - - if (!arena->curr) - return nullptr; - - try_alloc_again: - DN_ArenaBlock *curr = arena->curr; - bool poison = DN_ASAN_POISON && ((arena->flags & DN_ArenaFlags_NoPoison) == 0); - uint8_t real_align = poison ? DN_Max(align, DN_ASAN_POISON_ALIGNMENT) : align; - DN_U64 offset_pos = DN_AlignUpPowerOfTwo(curr->used, real_align) + (poison ? DN_ASAN_POISON_GUARD_SIZE : 0); - DN_U64 end_pos = offset_pos + size; - DN_U64 alloc_size = end_pos - curr->used; - - if (end_pos > curr->reserve) { - if (arena->flags & (DN_ArenaFlags_NoGrow | DN_ArenaFlags_UserBuffer)) - return nullptr; - DN_USize new_reserve = DN_Max(DN_ARENA_HEADER_SIZE + alloc_size, DN_ARENA_RESERVE_SIZE); - DN_USize new_commit = DN_Max(DN_ARENA_HEADER_SIZE + alloc_size, DN_ARENA_COMMIT_SIZE); - if (!DN_Arena_Grow(arena, new_reserve, new_commit)) - return nullptr; - goto try_alloc_again; - } - - DN_USize prev_arena_commit = curr->commit; - if (end_pos > curr->commit) { - DN_Assert(arena->mem_funcs.vmem_page_size); - DN_Assert(arena->mem_funcs.type == DN_ArenaMemFuncType_VMem); - DN_Assert((arena->flags & DN_ArenaFlags_UserBuffer) == 0); - DN_USize end_commit = DN_AlignUpPowerOfTwo(end_pos, arena->mem_funcs.vmem_page_size); - DN_USize commit_size = end_commit - curr->commit; - char *commit_ptr = DN_CAST(char *) curr + curr->commit; - if (!arena->mem_funcs.vmem_commit(commit_ptr, commit_size, DN_MemPage_ReadWrite)) - return nullptr; - if (poison) - DN_ASanPoisonMemoryRegion(commit_ptr, commit_size); - curr->commit = end_commit; - arena->stats.info.commit += commit_size; - arena->stats.hwm.commit = DN_Max(arena->stats.hwm.commit, arena->stats.info.commit); - } - - void *result = DN_CAST(char *) curr + offset_pos; - curr->used += alloc_size; - arena->stats.info.used += alloc_size; - arena->stats.hwm.used = DN_Max(arena->stats.hwm.used, arena->stats.info.used); - DN_ASanUnpoisonMemoryRegion(result, size); - - if (zero_mem == DN_ZeroMem_Yes) { - DN_USize reused_bytes = DN_Min(prev_arena_commit - offset_pos, size); - DN_Memset(result, 0, reused_bytes); - } - - DN_Assert(arena->stats.hwm.used >= arena->stats.info.used); - DN_Assert(arena->stats.hwm.commit >= arena->stats.info.commit); - DN_Assert(arena->stats.hwm.reserve >= arena->stats.info.reserve); - DN_Assert(arena->stats.hwm.blocks >= arena->stats.info.blocks); - return result; -} - -DN_API void *DN_Arena_AllocContiguous(DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZeroMem zero_mem) -{ - DN_ArenaFlags prev_flags = arena->flags; - arena->flags |= (DN_ArenaFlags_NoGrow | DN_ArenaFlags_NoPoison); - void *memory = DN_Arena_Alloc(arena, size, align, zero_mem); - arena->flags = prev_flags; - return memory; -} - -DN_API void *DN_Arena_Copy(DN_Arena *arena, void const *data, DN_U64 size, uint8_t align) -{ - if (!arena || !data || size == 0) - return nullptr; - void *result = DN_Arena_Alloc(arena, size, align, DN_ZeroMem_No); - if (result) - DN_Memcpy(result, data, size); - return result; -} - -DN_API void DN_Arena_PopTo(DN_Arena *arena, DN_U64 init_used) -{ - if (!arena || !arena->curr) - return; - DN_U64 used = DN_Max(DN_ARENA_HEADER_SIZE, init_used); - DN_ArenaBlock *curr = arena->curr; - while (curr->reserve_sum >= used) { - DN_ArenaBlock *block_to_free = curr; - arena->stats.info.used -= block_to_free->used; - arena->stats.info.commit -= block_to_free->commit; - arena->stats.info.reserve -= block_to_free->reserve; - arena->stats.info.blocks -= 1; - if (arena->flags & DN_ArenaFlags_UserBuffer) - break; - curr = curr->prev; - DN_Arena_BlockDeinit_(arena, block_to_free); - } - - arena->stats.info.used -= curr->used; - arena->curr = curr; - curr->used = used - curr->reserve_sum; - char *poison_ptr = (char *)curr + DN_AlignUpPowerOfTwo(curr->used, DN_ASAN_POISON_ALIGNMENT); - DN_USize poison_size = ((char *)curr + curr->commit) - poison_ptr; - DN_ASanPoisonMemoryRegion(poison_ptr, poison_size); - arena->stats.info.used += curr->used; -} - -DN_API void DN_Arena_Pop(DN_Arena *arena, DN_U64 amount) -{ - DN_ArenaBlock *curr = arena->curr; - DN_USize used_sum = curr->reserve_sum + curr->used; - if (!DN_Check(amount <= used_sum)) - amount = used_sum; - DN_USize pop_to = used_sum - amount; - DN_Arena_PopTo(arena, pop_to); -} - -DN_API DN_U64 DN_Arena_Pos(DN_Arena const *arena) -{ - DN_U64 result = (arena && arena->curr) ? arena->curr->reserve_sum + arena->curr->used : 0; - return result; -} - -DN_API void DN_Arena_Clear(DN_Arena *arena) -{ - DN_Arena_PopTo(arena, 0); -} - -DN_API bool DN_Arena_OwnsPtr(DN_Arena const *arena, void *ptr) -{ - bool result = false; - uintptr_t uint_ptr = DN_CAST(uintptr_t) ptr; - for (DN_ArenaBlock const *block = arena ? arena->curr : nullptr; !result && block; block = block->prev) { - uintptr_t begin = DN_CAST(uintptr_t) block + DN_ARENA_HEADER_SIZE; - uintptr_t end = begin + block->reserve; - result = uint_ptr >= begin && uint_ptr <= end; - } - return result; -} - -DN_API DN_ArenaStats DN_Arena_SumStatsArray(DN_ArenaStats const *array, DN_USize size) -{ - DN_ArenaStats result = {}; - for (DN_ForItSize(it, DN_ArenaStats const, array, size)) { - DN_ArenaStats stats = *it.data; - result.info.used += stats.info.used; - result.info.commit += stats.info.commit; - result.info.reserve += stats.info.reserve; - result.info.blocks += stats.info.blocks; - - result.hwm.used = DN_Max(result.hwm.used, result.info.used); - result.hwm.commit = DN_Max(result.hwm.commit, result.info.commit); - result.hwm.reserve = DN_Max(result.hwm.reserve, result.info.reserve); - result.hwm.blocks = DN_Max(result.hwm.blocks, result.info.blocks); - } - return result; -} - -DN_API DN_ArenaStats DN_Arena_SumStats(DN_ArenaStats lhs, DN_ArenaStats rhs) -{ - DN_ArenaStats array[] = {lhs, rhs}; - DN_ArenaStats result = DN_Arena_SumStatsArray(array, DN_ArrayCountU(array)); - return result; -} - -DN_API DN_ArenaStats DN_Arena_SumArenaArrayToStats(DN_Arena const *array, DN_USize size) -{ - DN_ArenaStats result = {}; - for (DN_USize index = 0; index < size; index++) { - DN_Arena const *arena = array + index; - result = DN_Arena_SumStats(result, arena->stats); - } - return result; -} - -DN_API DN_ArenaTempMem DN_Arena_TempMemBegin(DN_Arena *arena) -{ - DN_ArenaTempMem result = {}; - if (arena) { - DN_ArenaBlock *curr = arena->curr; - result = {arena, curr ? curr->reserve_sum + curr->used : 0}; - } - return result; -}; - -DN_API void DN_Arena_TempMemEnd(DN_ArenaTempMem mem) -{ - DN_Arena_PopTo(mem.arena, mem.used_sum); -}; - -DN_ArenaTempMemScope::DN_ArenaTempMemScope(DN_Arena *arena) -{ - mem = DN_Arena_TempMemBegin(arena); -} - -DN_ArenaTempMemScope::~DN_ArenaTempMemScope() -{ - DN_Arena_TempMemEnd(mem); -} - -// NOTE: DN_Pool /////////////////////////////////////////////////////////////////////////////////// -DN_API DN_Pool DN_Pool_FromArena(DN_Arena *arena, uint8_t align) -{ - DN_Pool result = {}; - if (arena) { - result.arena = arena; - result.align = align ? align : DN_POOL_DEFAULT_ALIGN; - } - return result; -} - -DN_API bool DN_Pool_IsValid(DN_Pool const *pool) -{ - bool result = pool && pool->arena && pool->align; - return result; -} - -DN_API void *DN_Pool_Alloc(DN_Pool *pool, DN_USize size) -{ - void *result = nullptr; - if (!DN_Pool_IsValid(pool)) - return result; - - DN_USize const required_size = sizeof(DN_PoolSlot) + pool->align + size; - DN_USize const size_to_slot_offset = 5; // __lzcnt64(32) e.g. DN_PoolSlotSize_32B - DN_USize slot_index = 0; - if (required_size > 32) { - // NOTE: Round up if not PoT as the low bits are set. - DN_USize dist_to_next_msb = DN_CountLeadingZerosUSize(required_size) + 1; - dist_to_next_msb -= DN_CAST(DN_USize)(!DN_IsPowerOfTwo(required_size)); - - DN_USize const register_size = sizeof(DN_USize) * 8; - DN_AssertF(register_size >= (dist_to_next_msb - size_to_slot_offset), "lhs=%zu, rhs=%zu", register_size, (dist_to_next_msb - size_to_slot_offset)); - slot_index = register_size - dist_to_next_msb - size_to_slot_offset; - } - - if (!DN_CheckF(slot_index < DN_PoolSlotSize_Count, "Chunk pool does not support the requested allocation size")) - return result; - - DN_USize slot_size_in_bytes = 1ULL << (slot_index + size_to_slot_offset); - DN_AssertF(required_size <= (slot_size_in_bytes << 0), "slot_index=%zu, lhs=%zu, rhs=%zu", slot_index, required_size, (slot_size_in_bytes << 0)); - DN_AssertF(required_size >= (slot_size_in_bytes >> 1), "slot_index=%zu, lhs=%zu, rhs=%zu", slot_index, required_size, (slot_size_in_bytes >> 1)); - - DN_PoolSlot *slot = nullptr; - if (pool->slots[slot_index]) { - slot = pool->slots[slot_index]; - pool->slots[slot_index] = slot->next; - DN_Memset(slot->data, 0, size); - DN_Assert(DN_IsPowerOfTwoAligned(slot->data, pool->align)); - } else { - void *bytes = DN_Arena_Alloc(pool->arena, slot_size_in_bytes, alignof(DN_PoolSlot), DN_ZeroMem_Yes); - slot = DN_CAST(DN_PoolSlot *) bytes; - - // NOTE: The raw pointer is round up to the next 'pool->align'-ed - // address ensuring at least 1 byte of padding between the raw pointer - // and the pointer given to the user and that the user pointer is - // aligned to the pool's alignment. - // - // This allows us to smuggle 1 byte behind the user pointer that has - // the offset to the original pointer. - slot->data = DN_CAST(void *) DN_AlignDownPowerOfTwo(DN_CAST(uintptr_t) slot + sizeof(DN_PoolSlot) + pool->align, pool->align); - - uintptr_t offset_to_original_ptr = DN_CAST(uintptr_t) slot->data - DN_CAST(uintptr_t) bytes; - DN_Assert(slot->data > bytes); - DN_Assert(offset_to_original_ptr <= sizeof(DN_PoolSlot) + pool->align); - - // NOTE: Store the offset to the original pointer behind the user's - // pointer. - char *offset_to_original_storage = DN_CAST(char *) slot->data - 1; - DN_Memcpy(offset_to_original_storage, &offset_to_original_ptr, 1); - } - - // NOTE: Smuggle the slot type in the next pointer so that we know, when the - // pointer gets returned which free list to return the pointer to. - result = slot->data; - slot->next = DN_CAST(DN_PoolSlot *) slot_index; - return result; -} - -DN_API DN_Str8 DN_Pool_AllocStr8FV(DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, va_list args) -{ - DN_Str8 result = {}; - if (!DN_Pool_IsValid(pool)) - return result; - - DN_USize size_required = DN_CStr8_FVSize(fmt, args); - result.data = DN_CAST(char *) DN_Pool_Alloc(pool, size_required + 1); - if (result.data) { - result.size = size_required; - DN_VSNPrintF(result.data, DN_CAST(int)(result.size + 1), fmt, args); - } - return result; -} - -DN_API DN_Str8 DN_Pool_AllocStr8F(DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...) -{ - va_list args; - va_start(args, fmt); - DN_Str8 result = DN_Pool_AllocStr8FV(pool, fmt, args); - va_end(args); - return result; -} - -DN_API DN_Str8 DN_Pool_AllocStr8Copy(DN_Pool *pool, DN_Str8 string) -{ - DN_Str8 result = {}; - if (!DN_Pool_IsValid(pool)) - return result; - - if (!DN_Str8_HasData(string)) - return result; - - char *data = DN_CAST(char *) DN_Pool_Alloc(pool, string.size + 1); - if (!data) - return result; - - DN_Memcpy(data, string.data, string.size); - data[string.size] = 0; - result = DN_Str8_Init(data, string.size); - return result; -} - -DN_API void DN_Pool_Dealloc(DN_Pool *pool, void *ptr) -{ - if (!DN_Pool_IsValid(pool) || !ptr) - return; - - DN_Assert(DN_Arena_OwnsPtr(pool->arena, ptr)); - - char const *one_byte_behind_ptr = DN_CAST(char *) ptr - 1; - DN_USize offset_to_original_ptr = 0; - DN_Memcpy(&offset_to_original_ptr, one_byte_behind_ptr, 1); - DN_Assert(offset_to_original_ptr <= sizeof(DN_PoolSlot) + pool->align); - - char *original_ptr = DN_CAST(char *) ptr - offset_to_original_ptr; - DN_PoolSlot *slot = DN_CAST(DN_PoolSlot *) original_ptr; - DN_PoolSlotSize slot_index = DN_CAST(DN_PoolSlotSize)(DN_CAST(uintptr_t) slot->next); - DN_Assert(slot_index < DN_PoolSlotSize_Count); - - slot->next = pool->slots[slot_index]; - pool->slots[slot_index] = slot; -} - -DN_API void *DN_Pool_Copy(DN_Pool *pool, void const *data, DN_U64 size, uint8_t align) -{ - if (!pool || !data || size == 0) - return nullptr; - - // TODO: Hmm should align be part of the alloc interface in general? I'm not going to worry - // about this until we crash because of misalignment. - DN_Assert(pool->align >= align); - - void *result = DN_Pool_Alloc(pool, size); - if (result) - DN_Memcpy(result, data, size); - return result; -} -// DN: Single header generator inlined this file => #include "Base/dn_base_string.cpp" -#define DN_STRING_CPP - -// DN: Single header generator commented out this header => #include "../dn_base_inc.h" - -// NOTE: DN_CStr8 ////////////////////////////////////////////////////////////////////////////////// -DN_API DN_USize DN_CStr8_FSize(DN_FMT_ATTRIB char const *fmt, ...) -{ - va_list args; - va_start(args, fmt); - DN_USize result = DN_VSNPrintF(nullptr, 0, fmt, args); - va_end(args); - return result; -} - -DN_API DN_USize DN_CStr8_FVSize(DN_FMT_ATTRIB char const *fmt, va_list args) -{ - va_list args_copy; - va_copy(args_copy, args); - DN_USize result = DN_VSNPrintF(nullptr, 0, fmt, args_copy); - va_end(args_copy); - return result; -} - -DN_API DN_USize DN_CStr8_Size(char const *src) -{ - DN_USize result = 0; - while (src && src[0] != 0) { - src++; - result++; - } - return result; -} - -DN_API DN_USize DN_CStr16_Size(wchar_t const *src) -{ - DN_USize result = 0; - while (src && src[0] != 0) { - src++; - result++; - } - - return result; -} - -// NOTE: DN_Str16 ////////////////////////////////////////////////////////////////////////////////// -DN_API bool operator==(DN_Str16 const &lhs, DN_Str16 const &rhs) -{ - bool result = false; - if (lhs.size == rhs.size) - result = DN_Memcmp(lhs.data, rhs.data, lhs.size * sizeof(*lhs.data)) == 0; - return result; -} - -DN_API bool operator!=(DN_Str16 const &lhs, DN_Str16 const &rhs) -{ - bool result = !(lhs == rhs); - return result; -} - -// NOTE: DN_Str8 /////////////////////////////////////////////////////////////////////////////////// -DN_API DN_Str8 DN_Str8_Alloc(DN_Arena *arena, DN_USize size, DN_ZeroMem zero_mem) -{ - DN_Str8 result = {}; - result.data = DN_Arena_NewArray(arena, char, size + 1, zero_mem); - if (result.data) - result.size = size; - result.data[result.size] = 0; - return result; -} - -DN_API DN_Str8 DN_Str8_AllocPool(DN_Pool *pool, DN_USize size) -{ - DN_Str8 result = {}; - result.data = DN_Pool_NewArray(pool, char, size + 1); - if (result.data) - result.size = size; - result.data[result.size] = 0; - return result; -} - -DN_API DN_Str8 DN_Str8_FromCStr8(char const *src) -{ - DN_USize size = DN_CStr8_Size(src); - DN_Str8 result = DN_Str8_Init(src, size); - return result; -} - -DN_API DN_Str8 DN_Str8_FromF(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...) -{ - va_list va; - va_start(va, fmt); - DN_Str8 result = DN_Str8_FromFV(arena, fmt, va); - va_end(va); - return result; -} - -DN_API DN_Str8 DN_Str8_FromFPool(DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...) -{ - va_list args; - va_start(args, fmt); - DN_USize size = DN_CStr8_FVSize(fmt, args); - va_end(args); - - DN_Str8 result = {}; - if (size) - result = DN_Str8_AllocPool(pool, size); - if (result.data) - DN_VSNPrintF(result.data, DN_SaturateCastISizeToInt(size + 1 /*null-terminator*/), fmt, args); - return result; -} - -DN_API DN_Str8 DN_Str8_FromFV(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args) -{ - DN_Str8 result = {}; - if (!fmt) - return result; - - DN_USize size = DN_CStr8_FVSize(fmt, args); - if (size) { - result = DN_Str8_Alloc(arena, size, DN_ZeroMem_No); - if (DN_Str8_HasData(result)) - DN_VSNPrintF(result.data, DN_SaturateCastISizeToInt(size + 1 /*null-terminator*/), fmt, args); - } - return result; -} - -DN_API bool DN_Str8_IsAll(DN_Str8 string, DN_Str8IsAll is_all) -{ - bool result = DN_Str8_HasData(string); - if (!result) - return result; - - switch (is_all) { - case DN_Str8IsAll_Digits: { - for (DN_USize index = 0; result && index < string.size; index++) - result = string.data[index] >= '0' && string.data[index] <= '9'; - } break; - - case DN_Str8IsAll_Hex: { - DN_Str8 trimmed = DN_Str8_TrimPrefix(string, DN_STR8("0x"), DN_Str8EqCase_Insensitive); - for (DN_USize index = 0; result && index < trimmed.size; index++) { - char ch = trimmed.data[index]; - result = (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F'); - } - } break; - } - - return result; -} - -DN_API char *DN_Str8_End(DN_Str8 string) -{ - char *result = string.data + string.size; - return result; -} - -DN_API DN_Str8 DN_Str8_Slice(DN_Str8 string, DN_USize offset, DN_USize size) -{ - DN_Str8 result = DN_Str8_Init(string.data, 0); - if (!DN_Str8_HasData(string)) - return result; - - DN_USize capped_offset = DN_Min(offset, string.size); - DN_USize max_size = string.size - capped_offset; - DN_USize capped_size = DN_Min(size, max_size); - result = DN_Str8_Init(string.data + capped_offset, capped_size); - return result; -} - -DN_API DN_Str8 DN_Str8_Advance(DN_Str8 string, DN_USize amount) -{ - DN_Str8 result = DN_Str8_Slice(string, amount, DN_USIZE_MAX); - return result; -} - -DN_API DN_Str8 DN_Str8_NextLine(DN_Str8 string) -{ - DN_Str8 result = DN_Str8_BSplit(string, DN_STR8("\n")).rhs; - return result; -} - -DN_API DN_Str8BSplitResult DN_Str8_BSplitArray(DN_Str8 string, DN_Str8 const *find, DN_USize find_size) -{ - DN_Str8BSplitResult result = {}; - if (!DN_Str8_HasData(string) || !find || find_size == 0) - return result; - - result.lhs = string; - for (size_t index = 0; !result.rhs.data && index < string.size; index++) { - for (DN_USize find_index = 0; find_index < find_size; find_index++) { - DN_Str8 find_item = find[find_index]; - DN_Str8 string_slice = DN_Str8_Slice(string, index, find_item.size); - if (DN_Str8_Eq(string_slice, find_item)) { - result.lhs.size = index; - result.rhs.data = string_slice.data + find_item.size; - result.rhs.size = string.size - (index + find_item.size); - break; - } - } - } - - return result; -} - -DN_API DN_Str8BSplitResult DN_Str8_BSplit(DN_Str8 string, DN_Str8 find) -{ - DN_Str8BSplitResult result = DN_Str8_BSplitArray(string, &find, 1); - return result; -} - -DN_API DN_Str8BSplitResult DN_Str8_BSplitLastArray(DN_Str8 string, DN_Str8 const *find, DN_USize find_size) -{ - DN_Str8BSplitResult result = {}; - if (!DN_Str8_HasData(string) || !find || find_size == 0) - return result; - - result.lhs = string; - for (size_t index = string.size - 1; !result.rhs.data && index < string.size; index--) { - for (DN_USize find_index = 0; find_index < find_size; find_index++) { - DN_Str8 find_item = find[find_index]; - DN_Str8 string_slice = DN_Str8_Slice(string, index, find_item.size); - if (DN_Str8_Eq(string_slice, find_item)) { - result.lhs.size = index; - result.rhs.data = string_slice.data + find_item.size; - result.rhs.size = string.size - (index + find_item.size); - break; - } - } - } - - return result; -} - -DN_API DN_Str8BSplitResult DN_Str8_BSplitLast(DN_Str8 string, DN_Str8 find) -{ - DN_Str8BSplitResult result = DN_Str8_BSplitLastArray(string, &find, 1); - return result; -} - -DN_API DN_USize DN_Str8_Split(DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_USize splits_count, DN_Str8SplitIncludeEmptyStrings mode) -{ - DN_USize result = 0; // The number of splits in the actual string. - if (!DN_Str8_HasData(string) || !DN_Str8_HasData(delimiter) || delimiter.size <= 0) - return result; - - DN_Str8BSplitResult split = {}; - DN_Str8 first = string; - do { - split = DN_Str8_BSplit(first, delimiter); - if (split.lhs.size || mode == DN_Str8SplitIncludeEmptyStrings_Yes) { - if (splits && result < splits_count) - splits[result] = split.lhs; - result++; - } - first = split.rhs; - } while (first.size); - - return result; -} - -DN_API DN_Slice DN_Str8_SplitAlloc(DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode) -{ - DN_Slice result = {}; - DN_USize splits_required = DN_Str8_Split(string, delimiter, /*splits*/ nullptr, /*count*/ 0, mode); - result.data = DN_Arena_NewArray(arena, DN_Str8, splits_required, DN_ZeroMem_No); - if (result.data) { - result.size = DN_Str8_Split(string, delimiter, result.data, splits_required, mode); - DN_Assert(splits_required == result.size); - } - return result; -} - -DN_API DN_Str8FindResult DN_Str8_FindStr8Array(DN_Str8 string, DN_Str8 const *find, DN_USize find_size, DN_Str8EqCase eq_case) -{ - DN_Str8FindResult result = {}; - for (DN_USize index = 0; !result.found && index < string.size; index++) { - for (DN_USize find_index = 0; find_index < find_size; find_index++) { - DN_Str8 find_item = find[find_index]; - DN_Str8 string_slice = DN_Str8_Slice(string, index, find_item.size); - if (DN_Str8_Eq(string_slice, find_item, eq_case)) { - result.found = true; - result.index = index; - result.start_to_before_match = DN_Str8_Init(string.data, index); - result.match = DN_Str8_Init(string.data + index, find_item.size); - result.match_to_end_of_buffer = DN_Str8_Init(result.match.data, string.size - index); - result.after_match_to_end_of_buffer = DN_Str8_Advance(result.match_to_end_of_buffer, find_item.size); - break; - } - } - } - return result; -} - -DN_API DN_Str8FindResult DN_Str8_FindStr8(DN_Str8 string, DN_Str8 find, DN_Str8EqCase eq_case) -{ - DN_Str8FindResult result = DN_Str8_FindStr8Array(string, &find, 1, eq_case); - return result; -} - -DN_API DN_Str8FindResult DN_Str8_Find(DN_Str8 string, uint32_t flags) -{ - DN_Str8FindResult result = {}; - for (size_t index = 0; !result.found && index < string.size; index++) { - result.found |= ((flags & DN_Str8FindFlag_Digit) && DN_Char_IsDigit(string.data[index])); - result.found |= ((flags & DN_Str8FindFlag_Alphabet) && DN_Char_IsAlphabet(string.data[index])); - result.found |= ((flags & DN_Str8FindFlag_Whitespace) && DN_Char_IsWhitespace(string.data[index])); - result.found |= ((flags & DN_Str8FindFlag_Plus) && string.data[index] == '+'); - result.found |= ((flags & DN_Str8FindFlag_Minus) && string.data[index] == '-'); - if (result.found) { - result.index = index; - result.match = DN_Str8_Init(string.data + index, 1); - result.match_to_end_of_buffer = DN_Str8_Init(result.match.data, string.size - index); - result.after_match_to_end_of_buffer = DN_Str8_Advance(result.match_to_end_of_buffer, 1); - } - } - return result; -} - -DN_API DN_Str8 DN_Str8_Segment(DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char) -{ - if (!segment_size || !DN_Str8_HasData(src)) { - DN_Str8 result = DN_Str8_FromStr8(arena, src); - return result; - } - - DN_USize segments = src.size / segment_size; - if (src.size % segment_size == 0) - segments--; - - DN_USize segment_counter = 0; - DN_Str8 result = DN_Str8_Alloc(arena, src.size + segments, DN_ZeroMem_Yes); - DN_USize write_index = 0; - for (DN_ForIndexU(src_index, src.size)) { - result.data[write_index++] = src.data[src_index]; - if ((src_index + 1) % segment_size == 0 && segment_counter < segments) { - result.data[write_index++] = segment_char; - segment_counter++; - } - DN_AssertF(write_index <= result.size, "result.size=%zu, write_index=%zu", result.size, write_index); - } - - DN_AssertF(write_index == result.size, "result.size=%zu, write_index=%zu", result.size, write_index); - return result; -} - -DN_API DN_Str8 DN_Str8_ReverseSegment(DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char) -{ - if (!segment_size || !DN_Str8_HasData(src)) { - DN_Str8 result = DN_Str8_FromStr8(arena, src); - return result; - } - - DN_USize segments = src.size / segment_size; - if (src.size % segment_size == 0) - segments--; - - DN_USize write_counter = 0; - DN_USize segment_counter = 0; - DN_Str8 result = DN_Str8_Alloc(arena, src.size + segments, DN_ZeroMem_Yes); - DN_USize write_index = result.size - 1; - - DN_MSVC_WARNING_PUSH - DN_MSVC_WARNING_DISABLE(6293) // NOTE: Ill-defined loop - for (size_t src_index = src.size - 1; src_index < src.size; src_index--) { - DN_MSVC_WARNING_POP - result.data[write_index--] = src.data[src_index]; - if (++write_counter % segment_size == 0 && segment_counter < segments) { - result.data[write_index--] = segment_char; - segment_counter++; - } - } - - DN_Assert(write_index == SIZE_MAX); - return result; -} - -DN_API bool DN_Str8_Eq(DN_Str8 lhs, DN_Str8 rhs, DN_Str8EqCase eq_case) -{ - if (lhs.size != rhs.size) - return false; - - if (lhs.size == 0) - return true; - - if (!lhs.data || !rhs.data) - return false; - - bool result = true; - switch (eq_case) { - case DN_Str8EqCase_Sensitive: { - result = (DN_Memcmp(lhs.data, rhs.data, lhs.size) == 0); - } break; - - case DN_Str8EqCase_Insensitive: { - for (DN_USize index = 0; index < lhs.size && result; index++) - result = (DN_Char_ToLower(lhs.data[index]) == DN_Char_ToLower(rhs.data[index])); - } break; - } - return result; -} - -DN_API bool DN_Str8_EqInsensitive(DN_Str8 lhs, DN_Str8 rhs) -{ - bool result = DN_Str8_Eq(lhs, rhs, DN_Str8EqCase_Insensitive); - return result; -} - -DN_API bool DN_Str8_StartsWith(DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case) -{ - DN_Str8 substring = {string.data, DN_Min(prefix.size, string.size)}; - bool result = DN_Str8_Eq(substring, prefix, eq_case); - return result; -} - -DN_API bool DN_Str8_StartsWithInsensitive(DN_Str8 string, DN_Str8 prefix) -{ - bool result = DN_Str8_StartsWith(string, prefix, DN_Str8EqCase_Insensitive); - return result; -} - -DN_API bool DN_Str8_EndsWith(DN_Str8 string, DN_Str8 suffix, DN_Str8EqCase eq_case) -{ - DN_Str8 substring = {string.data + string.size - suffix.size, DN_Min(string.size, suffix.size)}; - bool result = DN_Str8_Eq(substring, suffix, eq_case); - return result; -} - -DN_API bool DN_Str8_EndsWithInsensitive(DN_Str8 string, DN_Str8 suffix) -{ - bool result = DN_Str8_EndsWith(string, suffix, DN_Str8EqCase_Insensitive); - return result; -} - -DN_API bool DN_Str8_HasChar(DN_Str8 string, char ch) -{ - bool result = false; - for (DN_USize index = 0; !result && index < string.size; index++) - result = string.data[index] == ch; - return result; -} - -DN_API DN_Str8 DN_Str8_TrimPrefix(DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case) -{ - DN_Str8 result = string; - if (DN_Str8_StartsWith(string, prefix, eq_case)) { - result.data += prefix.size; - result.size -= prefix.size; - } - return result; -} - -DN_API DN_Str8 DN_Str8_TrimHexPrefix(DN_Str8 string) -{ - DN_Str8 result = DN_Str8_TrimPrefix(string, DN_STR8("0x"), DN_Str8EqCase_Insensitive); - return result; -} - -DN_API DN_Str8 DN_Str8_TrimSuffix(DN_Str8 string, DN_Str8 suffix, DN_Str8EqCase eq_case) -{ - DN_Str8 result = string; - if (DN_Str8_EndsWith(string, suffix, eq_case)) - result.size -= suffix.size; - return result; -} - -DN_API DN_Str8 DN_Str8_TrimAround(DN_Str8 string, DN_Str8 trim_string) -{ - DN_Str8 result = DN_Str8_TrimPrefix(string, trim_string); - result = DN_Str8_TrimSuffix(result, trim_string); - return result; -} - -DN_API DN_Str8 DN_Str8_TrimHeadWhitespace(DN_Str8 string) -{ - DN_Str8 result = string; - if (!DN_Str8_HasData(string)) - return result; - - char const *start = string.data; - char const *end = string.data + string.size; - while (start < end && DN_Char_IsWhitespace(start[0])) - start++; - - result = DN_Str8_Init(start, end - start); - return result; -} - -DN_API DN_Str8 DN_Str8_TrimTailWhitespace(DN_Str8 string) -{ - DN_Str8 result = string; - if (!DN_Str8_HasData(string)) - return result; - - char const *start = string.data; - char const *end = string.data + string.size; - while (end > start && DN_Char_IsWhitespace(end[-1])) - end--; - - result = DN_Str8_Init(start, end - start); - return result; -} - -DN_API DN_Str8 DN_Str8_TrimWhitespaceAround(DN_Str8 string) -{ - DN_Str8 result = DN_Str8_TrimHeadWhitespace(string); - result = DN_Str8_TrimTailWhitespace(result); - return result; -} - -DN_API DN_Str8 DN_Str8_TrimByteOrderMark(DN_Str8 string) -{ - DN_Str8 result = string; - if (!DN_Str8_HasData(result)) - return result; - - // TODO(dn): This is little endian - DN_Str8 UTF8_BOM = DN_STR8("\xEF\xBB\xBF"); - DN_Str8 UTF16_BOM_BE = DN_STR8("\xEF\xFF"); - DN_Str8 UTF16_BOM_LE = DN_STR8("\xFF\xEF"); - DN_Str8 UTF32_BOM_BE = DN_STR8("\x00\x00\xFE\xFF"); - DN_Str8 UTF32_BOM_LE = DN_STR8("\xFF\xFE\x00\x00"); - - result = DN_Str8_TrimPrefix(result, UTF8_BOM, DN_Str8EqCase_Sensitive); - result = DN_Str8_TrimPrefix(result, UTF16_BOM_BE, DN_Str8EqCase_Sensitive); - result = DN_Str8_TrimPrefix(result, UTF16_BOM_LE, DN_Str8EqCase_Sensitive); - result = DN_Str8_TrimPrefix(result, UTF32_BOM_BE, DN_Str8EqCase_Sensitive); - result = DN_Str8_TrimPrefix(result, UTF32_BOM_LE, DN_Str8EqCase_Sensitive); - return result; -} - -DN_API DN_Str8 DN_Str8_FileNameFromPath(DN_Str8 path) -{ - DN_Str8 separators[] = {DN_STR8("/"), DN_STR8("\\")}; - DN_Str8BSplitResult split = DN_Str8_BSplitLastArray(path, separators, DN_ArrayCountU(separators)); - DN_Str8 result = DN_Str8_HasData(split.rhs) ? split.rhs : split.lhs; - return result; -} - -DN_API DN_Str8 DN_Str8_FileNameNoExtension(DN_Str8 path) -{ - DN_Str8 file_name = DN_Str8_FileNameFromPath(path); - DN_Str8 result = DN_Str8_FilePathNoExtension(file_name); - return result; -} - -DN_API DN_Str8 DN_Str8_FilePathNoExtension(DN_Str8 path) -{ - DN_Str8BSplitResult split = DN_Str8_BSplitLast(path, DN_STR8(".")); - DN_Str8 result = split.lhs; - return result; -} - -DN_API DN_Str8 DN_Str8_FileExtension(DN_Str8 path) -{ - DN_Str8BSplitResult split = DN_Str8_BSplitLast(path, DN_STR8(".")); - DN_Str8 result = split.rhs; - return result; -} - -DN_API DN_Str8 DN_Str8_FileDirectoryFromPath(DN_Str8 path) -{ - DN_Str8 separators[] = {DN_STR8("/"), DN_STR8("\\")}; - DN_Str8BSplitResult split = DN_Str8_BSplitLastArray(path, separators, DN_ArrayCountU(separators)); - DN_Str8 result = split.lhs; - return result; -} - -DN_API DN_Str8ToU64Result DN_Str8_ToU64(DN_Str8 string, char separator) -{ - // NOTE: Argument check - DN_Str8ToU64Result result = {}; - if (!DN_Str8_HasData(string)) { - result.success = true; - return result; - } - - // NOTE: Sanitize input/output - DN_Str8 trim_string = DN_Str8_TrimWhitespaceAround(string); - if (trim_string.size == 0) { - result.success = true; - return result; - } - - // NOTE: Handle prefix '+' - DN_USize start_index = 0; - if (!DN_Char_IsDigit(trim_string.data[0])) { - if (trim_string.data[0] != '+') - return result; - start_index++; - } - - // NOTE: Convert the string number to the binary number - for (DN_USize index = start_index; index < trim_string.size; index++) { - char ch = trim_string.data[index]; - if (index) { - if (separator != 0 && ch == separator) - continue; - } - - if (!DN_Char_IsDigit(ch)) - return result; - - result.value = DN_SafeMulU64(result.value, 10); - uint64_t digit = ch - '0'; - result.value = DN_SafeAddU64(result.value, digit); - } - - result.success = true; - return result; -} - -DN_API DN_Str8ToI64Result DN_Str8_ToI64(DN_Str8 string, char separator) -{ - // NOTE: Argument check - DN_Str8ToI64Result result = {}; - if (!DN_Str8_HasData(string)) { - result.success = true; - return result; - } - - // NOTE: Sanitize input/output - DN_Str8 trim_string = DN_Str8_TrimWhitespaceAround(string); - if (trim_string.size == 0) { - result.success = true; - return result; - } - - bool negative = false; - DN_USize start_index = 0; - if (!DN_Char_IsDigit(trim_string.data[0])) { - negative = (trim_string.data[start_index] == '-'); - if (!negative && trim_string.data[0] != '+') - return result; - start_index++; - } - - // NOTE: Convert the string number to the binary number - for (DN_USize index = start_index; index < trim_string.size; index++) { - char ch = trim_string.data[index]; - if (index) { - if (separator != 0 && ch == separator) - continue; - } - - if (!DN_Char_IsDigit(ch)) - return result; - - result.value = DN_SafeMulU64(result.value, 10); - uint64_t digit = ch - '0'; - result.value = DN_SafeAddU64(result.value, digit); - } - - if (negative) - result.value *= -1; - - result.success = true; - return result; -} - -DN_API DN_Str8 DN_Str8_AppendF(DN_Arena *arena, DN_Str8 string, char const *fmt, ...) -{ - va_list args; - va_start(args, fmt); - DN_Str8 result = DN_Str8_AppendFV(arena, string, fmt, args); - va_end(args); - return result; -} - -DN_API DN_Str8 DN_Str8_AppendFV(DN_Arena *arena, DN_Str8 string, char const *fmt, va_list args) -{ - // TODO: Calculate size and write into one buffer instead of 2 appends - DN_Str8 append = DN_Str8_FromFV(arena, fmt, args); - DN_Str8 result = DN_Str8_Alloc(arena, string.size + append.size, DN_ZeroMem_No); - DN_Memcpy(result.data, string.data, string.size); - DN_Memcpy(result.data + string.size, append.data, append.size); - return result; -} - -DN_API DN_Str8 DN_Str8_FillF(DN_Arena *arena, DN_USize count, char const *fmt, ...) -{ - va_list args; - va_start(args, fmt); - DN_Str8 result = DN_Str8_FillFV(arena, count, fmt, args); - va_end(args); - return result; -} - -DN_API DN_Str8 DN_Str8_FillFV(DN_Arena *arena, DN_USize count, char const *fmt, va_list args) -{ - DN_Str8 fill = DN_Str8_FromFV(arena, fmt, args); - DN_Str8 result = DN_Str8_Alloc(arena, count * fill.size, DN_ZeroMem_No); - for (DN_USize index = 0; index < count; index++) { - void *dest = result.data + (index * fill.size); - DN_Memcpy(dest, fill.data, fill.size); - } - return result; -} - -DN_API void DN_Str8_Remove(DN_Str8 *string, DN_USize offset, DN_USize size) -{ - if (!string || !DN_Str8_HasData(*string)) - return; - - char *end = string->data + string->size; - char *dest = DN_Min(string->data + offset, end); - char *src = DN_Min(string->data + offset + size, end); - DN_USize bytes_to_move = end - src; - DN_Memmove(dest, src, bytes_to_move); - string->size -= bytes_to_move; -} - -DN_API DN_Str8DotTruncateResult DN_Str8_DotTruncateMiddle(DN_Arena *arena, DN_Str8 str8, uint32_t side_size, DN_Str8 truncator) -{ - DN_Str8DotTruncateResult result = {}; - if (str8.size <= (side_size * 2)) { - result.str8 = DN_Str8_FromStr8(arena, str8); - return result; - } - - DN_Str8 head = DN_Str8_Slice(str8, 0, side_size); - DN_Str8 tail = DN_Str8_Slice(str8, str8.size - side_size, side_size); - DN_MSVC_WARNING_PUSH - DN_MSVC_WARNING_DISABLE(6284) // Object passed as _Param_(3) when a string is required in call to 'DN_Str8_FromF' Actual type: 'struct DN_Str8' - result.str8 = DN_Str8_FromF(arena, "%S%S%S", head, truncator, tail); - DN_MSVC_WARNING_POP - result.truncated = true; - return result; -} - -DN_API DN_Str8 DN_Str8_Lower(DN_Arena *arena, DN_Str8 string) -{ - DN_Str8 result = DN_Str8_FromStr8(arena, string); - for (DN_ForIndexU(index, result.size)) - result.data[index] = DN_Char_ToLower(result.data[index]); - return result; -} - -DN_API DN_Str8 DN_Str8_Upper(DN_Arena *arena, DN_Str8 string) -{ - DN_Str8 result = DN_Str8_FromStr8(arena, string); - for (DN_ForIndexU(index, result.size)) - result.data[index] = DN_Char_ToUpper(result.data[index]); - return result; -} - -#if defined(__cplusplus) -DN_API bool operator==(DN_Str8 const &lhs, DN_Str8 const &rhs) -{ - bool result = DN_Str8_Eq(lhs, rhs, DN_Str8EqCase_Sensitive); - return result; -} - -DN_API bool operator!=(DN_Str8 const &lhs, DN_Str8 const &rhs) -{ - bool result = !(lhs == rhs); - return result; -} -#endif - -DN_API DN_Str8 DN_Str8_FromStr8(DN_Arena *arena, DN_Str8 string) -{ - DN_Str8 result = DN_Str8_Alloc(arena, string.size, DN_ZeroMem_No); - if (DN_Str8_HasData(result)) { - DN_Memcpy(result.data, string.data, string.size); - result.data[string.size] = 0; - } - return result; -} - -// NOTE: DN_Str8Builder //////////////////////////////////////////////////////////////////////////// -DN_API DN_Str8Builder DN_Str8Builder_FromArena(DN_Arena *arena) -{ - DN_Str8Builder result = {}; - result.arena = arena; - return result; -} - -DN_API DN_Str8Builder DN_Str8Builder_FromStr8PtrRef(DN_Arena *arena, DN_Str8 const *strings, DN_USize size) -{ - DN_Str8Builder result = DN_Str8Builder_FromArena(arena); - DN_Str8Builder_AppendArrayRef(&result, strings, size); - return result; -} - -DN_API DN_Str8Builder DN_Str8Builder_FromStr8PtrCopy(DN_Arena *arena, DN_Str8 const *strings, DN_USize size) -{ - DN_Str8Builder result = DN_Str8Builder_FromArena(arena); - DN_Str8Builder_AppendArrayCopy(&result, strings, size); - return result; -} - -DN_API DN_Str8Builder DN_Str8Builder_FromBuilder(DN_Arena *arena, DN_Str8Builder const *builder) -{ - DN_Str8Builder result = DN_Str8Builder_FromArena(arena); - DN_Str8Builder_AppendBuilderCopy(&result, builder); - return result; -} - - -DN_API bool DN_Str8Builder_AddArrayRef(DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize size, DN_Str8BuilderAdd add) -{ - if (!builder) - return false; - - if (!strings || size <= 0) - return true; - - DN_Str8Link *links = DN_Arena_NewArray(builder->arena, DN_Str8Link, size, DN_ZeroMem_No); - if (!links) - return false; - - if (add == DN_Str8BuilderAdd_Append) { - for (DN_ForIndexU(index, size)) { - DN_Str8 string = strings[index]; - DN_Str8Link *link = links + index; - - link->string = string; - link->next = NULL; - - if (builder->head) - builder->tail->next = link; - else - builder->head = link; - - builder->tail = link; - builder->count++; - builder->string_size += string.size; - } - } else { - DN_Assert(add == DN_Str8BuilderAdd_Prepend); - DN_MSVC_WARNING_PUSH - DN_MSVC_WARNING_DISABLE(6293) // NOTE: Ill-defined loop - for (DN_USize index = size - 1; index < size; index--) { - DN_MSVC_WARNING_POP - DN_Str8 string = strings[index]; - DN_Str8Link *link = links + index; - link->string = string; - link->next = builder->head; - builder->head = link; - if (!builder->tail) - builder->tail = link; - builder->count++; - builder->string_size += string.size; - } - } - return true; -} - -DN_API bool DN_Str8Builder_AddArrayCopy(DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize size, DN_Str8BuilderAdd add) -{ - if (!builder) - return false; - - if (!strings || size <= 0) - return true; - - DN_ArenaTempMem tmp_mem = DN_Arena_TempMemBegin(builder->arena); - bool result = true; - DN_Str8 *strings_copy = DN_Arena_NewArray(builder->arena, DN_Str8, size, DN_ZeroMem_No); - for (DN_ForIndexU(index, size)) { - strings_copy[index] = DN_Str8_FromStr8(builder->arena, strings[index]); - if (strings_copy[index].size != strings[index].size) { - result = false; - break; - } - } - - if (result) - result = DN_Str8Builder_AddArrayRef(builder, strings_copy, size, add); - - if (!result) - DN_Arena_TempMemEnd(tmp_mem); - - return result; -} - -DN_API bool DN_Str8Builder_AddFV(DN_Str8Builder *builder, DN_Str8BuilderAdd add, DN_FMT_ATTRIB char const *fmt, va_list args) -{ - DN_Str8 string = DN_Str8_FromFV(builder->arena, fmt, args); - DN_ArenaTempMem temp_mem = DN_Arena_TempMemBegin(builder->arena); - bool result = DN_Str8Builder_AddArrayRef(builder, &string, 1, add); - if (!result) - DN_Arena_TempMemEnd(temp_mem); - return result; -} - -DN_API bool DN_Str8Builder_AppendRef(DN_Str8Builder *builder, DN_Str8 string) -{ - bool result = DN_Str8Builder_AddArrayRef(builder, &string, 1, DN_Str8BuilderAdd_Append); - return result; -} - -DN_API bool DN_Str8Builder_AppendCopy(DN_Str8Builder *builder, DN_Str8 string) -{ - bool result = DN_Str8Builder_AddArrayCopy(builder, &string, 1, DN_Str8BuilderAdd_Append); - return result; -} - -DN_API bool DN_Str8Builder_AppendF(DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...) -{ - va_list args; - va_start(args, fmt); - bool result = DN_Str8Builder_AppendFV(builder, fmt, args); - va_end(args); - return result; -} - -DN_API bool DN_Str8Builder_AppendBytesRef(DN_Str8Builder *builder, void const *ptr, DN_USize size) -{ - DN_Str8 input = DN_Str8_Init(ptr, size); - bool result = DN_Str8Builder_AppendRef(builder, input); - return result; -} - -DN_API bool DN_Str8Builder_AppendBytesCopy(DN_Str8Builder *builder, void const *ptr, DN_USize size) -{ - DN_Str8 input = DN_Str8_Init(ptr, size); - bool result = DN_Str8Builder_AppendCopy(builder, input); - return result; -} - -static bool DN_Str8Builder_AppendBuilder_(DN_Str8Builder *dest, DN_Str8Builder const *src, bool copy) -{ - if (!dest) - return false; - if (!src) - return true; - - DN_Arena_TempMemBegin(dest->arena); - DN_Str8Link *links = DN_Arena_NewArray(dest->arena, DN_Str8Link, src->count, DN_ZeroMem_No); - if (!links) - return false; - - DN_Str8Link *first = nullptr; - DN_Str8Link *last = nullptr; - DN_USize link_index = 0; - bool result = true; - for (DN_Str8Link const *it = src->head; it; it = it->next) { - DN_Str8Link *link = links + link_index++; - link->next = nullptr; - link->string = it->string; - - if (copy) { - link->string = DN_Str8_FromStr8(dest->arena, it->string); - if (link->string.size != it->string.size) { - result = false; - break; - } - } - - if (last) - last->next = link; - else - first = link; - last = link; - } - - if (result) { - if (dest->head) - dest->tail->next = first; - else - dest->head = first; - dest->tail = last; - dest->count += src->count; - dest->string_size += src->string_size; - } - return true; -} - -DN_API bool DN_Str8Builder_AppendBuilderRef(DN_Str8Builder *dest, DN_Str8Builder const *src) -{ - bool result = DN_Str8Builder_AppendBuilder_(dest, src, false); - return result; -} - -DN_API bool DN_Str8Builder_AppendBuilderCopy(DN_Str8Builder *dest, DN_Str8Builder const *src) -{ - bool result = DN_Str8Builder_AppendBuilder_(dest, src, true); - return result; -} - -DN_API bool DN_Str8Builder_PrependRef(DN_Str8Builder *builder, DN_Str8 string) -{ - bool result = DN_Str8Builder_AddArrayRef(builder, &string, 1, DN_Str8BuilderAdd_Prepend); - return result; -} - -DN_API bool DN_Str8Builder_PrependCopy(DN_Str8Builder *builder, DN_Str8 string) -{ - bool result = DN_Str8Builder_AddArrayCopy(builder, &string, 1, DN_Str8BuilderAdd_Prepend); - return result; -} - -DN_API bool DN_Str8Builder_PrependF(DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...) -{ - va_list args; - va_start(args, fmt); - bool result = DN_Str8Builder_PrependFV(builder, fmt, args); - va_end(args); - return result; -} - -DN_API bool DN_Str8Builder_Erase(DN_Str8Builder *builder, DN_Str8 string) -{ - for (DN_Str8Link **it = &builder->head; *it; it = &((*it)->next)) { - if ((*it)->string == string) { - *it = (*it)->next; - builder->string_size -= string.size; - builder->count -= 1; - return true; - } - } - return false; -} - -DN_API DN_Str8 DN_Str8Builder_Build(DN_Str8Builder const *builder, DN_Arena *arena) -{ - DN_Str8 result = DN_Str8Builder_BuildDelimited(builder, DN_STR8(""), arena); - return result; -} - -DN_API DN_Str8 DN_Str8Builder_BuildDelimited(DN_Str8Builder const *builder, DN_Str8 delimiter, DN_Arena *arena) -{ - DN_Str8 result = DN_ZeroInit; - if (!builder || builder->string_size <= 0 || builder->count <= 0) - return result; - - DN_USize size_for_delimiter = DN_Str8_HasData(delimiter) ? ((builder->count - 1) * delimiter.size) : 0; - result.data = DN_Arena_NewArray(arena, - char, - builder->string_size + size_for_delimiter + 1 /*null terminator*/, - DN_ZeroMem_No); - if (!result.data) - return result; - - for (DN_Str8Link *link = builder->head; link; link = link->next) { - DN_Memcpy(result.data + result.size, link->string.data, link->string.size); - result.size += link->string.size; - if (link->next && DN_Str8_HasData(delimiter)) { - DN_Memcpy(result.data + result.size, delimiter.data, delimiter.size); - result.size += delimiter.size; - } - } - - result.data[result.size] = 0; - DN_Assert(result.size == builder->string_size + size_for_delimiter); - return result; -} - -DN_API DN_Slice DN_Str8Builder_BuildSlice(DN_Str8Builder const *builder, DN_Arena *arena) -{ - DN_Slice result = DN_ZeroInit; - if (!builder || builder->string_size <= 0 || builder->count <= 0) - return result; - - result = DN_Slice_Alloc(arena, builder->count, DN_ZeroMem_No); - if (!result.data) - return result; - - DN_USize slice_index = 0; - for (DN_Str8Link *link = builder->head; link; link = link->next) - result.data[slice_index++] = DN_Str8_FromStr8(arena, link->string); - - DN_Assert(slice_index == builder->count); - return result; -} - -DN_API DN_Str8 DN_LStr8_AppendFV(char *buf, DN_USize *buf_size, DN_USize buf_max, char const *fmt, va_list args) -{ - *buf_size += DN_VSNPrintF(buf + *buf_size, DN_CAST(int)(buf_max - *buf_size), fmt, args); - DN_Str8 result = DN_Str8_Init(buf, *buf_size); - return result; -} - -DN_API DN_Str8 DN_LStr8_AppendF(char *buf, DN_USize *buf_size, DN_USize buf_max, char const *fmt, ...) -{ - va_list args; - va_start(args, fmt); - DN_Str8 result = DN_LStr8_AppendFV(buf, buf_size, buf_max, fmt, args); - va_end(args); - return result; -} - -// NOTE: DN_Char /////////////////////////////////////////////////////////////////////////////////// -DN_API bool DN_Char_IsAlphabet(char ch) -{ - bool result = (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); - return result; -} - -DN_API bool DN_Char_IsDigit(char ch) -{ - bool result = (ch >= '0' && ch <= '9'); - return result; -} - -DN_API bool DN_Char_IsAlphaNum(char ch) -{ - bool result = DN_Char_IsAlphabet(ch) || DN_Char_IsDigit(ch); - return result; -} - -DN_API bool DN_Char_IsWhitespace(char ch) -{ - bool result = (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); - return result; -} - -DN_API bool DN_Char_IsHex(char ch) -{ - bool result = ((ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F') || (ch >= '0' && ch <= '9')); - return result; -} - -DN_API char DN_Char_ToLower(char ch) -{ - char result = ch; - if (result >= 'A' && result <= 'Z') - result += 'a' - 'A'; - return result; -} - -DN_API char DN_Char_ToUpper(char ch) -{ - char result = ch; - if (result >= 'a' && result <= 'z') - result -= 'a' - 'A'; - return result; -} - -// NOTE: DN_UTF //////////////////////////////////////////////////////////////////////////////////// -DN_API int DN_UTF8_EncodeCodepoint(uint8_t utf8[4], uint32_t codepoint) -{ - // NOTE: Table from https://www.reedbeta.com/blog/programmers-intro-to-unicode/ - // ----------------------------------------+----------------------------+--------------------+ - // UTF-8 (binary) | Code point (binary) | Range | - // ----------------------------------------+----------------------------+--------------------+ - // 0xxx'xxxx | xxx'xxxx | U+0000 - U+007F | - // 110x'xxxx 10yy'yyyy | xxx'xxyy'yyyy | U+0080 - U+07FF | - // 1110'xxxx 10yy'yyyy 10zz'zzzz | xxxx'yyyy'yyzz'zzzz | U+0800 - U+FFFF | - // 1111'0xxx 10yy'yyyy 10zz'zzzz 10ww'wwww | x'xxyy'yyyy'zzzz'zzww'wwww | U+10000 - U+10FFFF | - // ----------------------------------------+----------------------------+--------------------+ - - if (codepoint <= 0b0111'1111) { - utf8[0] = DN_CAST(uint8_t) codepoint; - return 1; - } - - if (codepoint <= 0b0111'1111'1111) { - utf8[0] = (0b1100'0000 | ((codepoint >> 6) & 0b01'1111)); // x - utf8[1] = (0b1000'0000 | ((codepoint >> 0) & 0b11'1111)); // y - return 2; - } - - if (codepoint <= 0b1111'1111'1111'1111) { - utf8[0] = (0b1110'0000 | ((codepoint >> 12) & 0b00'1111)); // x - utf8[1] = (0b1000'0000 | ((codepoint >> 6) & 0b11'1111)); // y - utf8[2] = (0b1000'0000 | ((codepoint >> 0) & 0b11'1111)); // z - return 3; - } - - if (codepoint <= 0b1'1111'1111'1111'1111'1111) { - utf8[0] = (0b1111'0000 | ((codepoint >> 18) & 0b00'0111)); // x - utf8[1] = (0b1000'0000 | ((codepoint >> 12) & 0b11'1111)); // y - utf8[2] = (0b1000'0000 | ((codepoint >> 6) & 0b11'1111)); // z - utf8[3] = (0b1000'0000 | ((codepoint >> 0) & 0b11'1111)); // w - return 4; - } - - return 0; -} - -DN_API int DN_UTF16_EncodeCodepoint(uint16_t utf16[2], uint32_t codepoint) -{ - // NOTE: Table from https://www.reedbeta.com/blog/programmers-intro-to-unicode/ - // ----------------------------------------+------------------------------------+------------------+ - // UTF-16 (binary) | Code point (binary) | Range | - // ----------------------------------------+------------------------------------+------------------+ - // xxxx'xxxx'xxxx'xxxx | xxxx'xxxx'xxxx'xxxx | U+0000???U+FFFF | - // 1101'10xx'xxxx'xxxx 1101'11yy'yyyy'yyyy | xxxx'xxxx'xxyy'yyyy'yyyy + 0x10000 | U+10000???U+10FFFF | - // ----------------------------------------+------------------------------------+------------------+ - - if (codepoint <= 0b1111'1111'1111'1111) { - utf16[0] = DN_CAST(uint16_t) codepoint; - return 1; - } - - if (codepoint <= 0b1111'1111'1111'1111'1111) { - uint32_t surrogate_codepoint = codepoint + 0x10000; - utf16[0] = 0b1101'1000'0000'0000 | ((surrogate_codepoint >> 10) & 0b11'1111'1111); // x - utf16[1] = 0b1101'1100'0000'0000 | ((surrogate_codepoint >> 0) & 0b11'1111'1111); // y - return 2; - } - - return 0; -} // DN: Single header generator inlined this file => #include "Base/dn_base_log.cpp" #define DN_BASE_LOG_CPP @@ -4420,9 +4384,9 @@ DN_API DN_Str8 DN_LOG_ColourEscapeCodeStr8FromRGB(DN_LOGColourType colour, DN_U8 DN_API DN_Str8 DN_LOG_ColourEscapeCodeStr8FromU32(DN_LOGColourType colour, DN_U32 value) { - DN_U8 r = DN_CAST(DN_U8)(value >> 24); - DN_U8 g = DN_CAST(DN_U8)(value >> 16); - DN_U8 b = DN_CAST(DN_U8)(value >> 8); + DN_U8 r = DN_Cast(DN_U8)(value >> 24); + DN_U8 g = DN_Cast(DN_U8)(value >> 16); + DN_U8 b = DN_Cast(DN_U8)(value >> 8); DN_Str8 result = DN_LOG_ColourEscapeCodeStr8FromRGB(colour, r, g, b); return result; } @@ -4432,35 +4396,35 @@ DN_API DN_LOGPrefixSize DN_LOG_MakePrefix(DN_LOGStyle style, DN_LOGTypeParam typ DN_Str8 type_str8 = type.str8; if (type.is_u32_enum) { switch (type.u32) { - case DN_LOGType_Debug: type_str8 = DN_STR8("DEBUG"); break; - case DN_LOGType_Info: type_str8 = DN_STR8("INFO "); break; - case DN_LOGType_Warning: type_str8 = DN_STR8("WARN"); break; - case DN_LOGType_Error: type_str8 = DN_STR8("ERROR"); break; - case DN_LOGType_Count: type_str8 = DN_STR8("BADXX"); break; + case DN_LOGType_Debug: type_str8 = DN_Str8Lit("DEBUG"); break; + case DN_LOGType_Info: type_str8 = DN_Str8Lit("INFO "); break; + case DN_LOGType_Warning: type_str8 = DN_Str8Lit("WARN"); break; + case DN_LOGType_Error: type_str8 = DN_Str8Lit("ERROR"); break; + case DN_LOGType_Count: type_str8 = DN_Str8Lit("BADXX"); break; } } static DN_USize max_type_length = 0; max_type_length = DN_Max(max_type_length, type_str8.size); - int type_padding = DN_CAST(int)(max_type_length - type_str8.size); + int type_padding = DN_Cast(int)(max_type_length - type_str8.size); DN_Str8 colour_esc = {}; DN_Str8 bold_esc = {}; DN_Str8 reset_esc = {}; if (style.colour) { - bold_esc = DN_STR8(DN_LOG_BoldEscapeCode); - reset_esc = DN_STR8(DN_LOG_ResetEscapeCode); + bold_esc = DN_Str8Lit(DN_LOG_BoldEscapeCode); + reset_esc = DN_Str8Lit(DN_LOG_ResetEscapeCode); colour_esc = DN_LOG_ColourEscapeCodeStr8FromRGB(DN_LOGColourType_Fg, style.r, style.g, style.b); } - DN_Str8 file_name = DN_Str8_FileNameFromPath(call_site.file); + DN_Str8 file_name = DN_Str8FileNameFromPath(call_site.file); DN_GCC_WARNING_PUSH DN_GCC_WARNING_DISABLE(-Wformat) DN_GCC_WARNING_DISABLE(-Wformat-extra-args) DN_MSVC_WARNING_PUSH DN_MSVC_WARNING_DISABLE(4477) int size = DN_SNPrintF(dest, - DN_CAST(int)dest_size, + DN_Cast(int)dest_size, "%04u-%02u-%02uT%02u:%02u:%02u" // date "%S" // colour "%S" // bold @@ -4479,7 +4443,7 @@ DN_API DN_LOGPrefixSize DN_LOG_MakePrefix(DN_LOGStyle style, DN_LOGTypeParam typ colour_esc, // colour bold_esc, // bold type_str8, // type - DN_CAST(int) type_padding, + DN_Cast(int) type_padding, "", // type padding reset_esc, // reset file_name, // file name @@ -4533,7 +4497,7 @@ DN_OSTLSTMem::DN_OSTLSTMem(DN_OSTLS *tls, DN_U8 arena_index, DN_OSTLSPushTMem pu { DN_Assert(arena_index == DN_OSTLSArena_TMem0 || arena_index == DN_OSTLSArena_TMem1); arena = tls->arenas + arena_index; - temp_mem = DN_Arena_TempMemBegin(arena); + temp_mem = DN_ArenaTempMemBegin(arena); destructed = false; push_arena = push_tmem; if (push_arena) @@ -4543,7 +4507,7 @@ DN_OSTLSTMem::DN_OSTLSTMem(DN_OSTLS *tls, DN_U8 arena_index, DN_OSTLSPushTMem pu DN_OSTLSTMem::~DN_OSTLSTMem() { DN_Assert(destructed == false); - DN_Arena_TempMemEnd(temp_mem); + DN_ArenaTempMemEnd(temp_mem); destructed = true; if (push_arena) DN_OS_TLSPopArena(); @@ -4565,9 +4529,9 @@ DN_API void DN_OS_TLSInit(DN_OSTLS *tls, DN_OSTLSInitArgs args) // for setting up the alloc tracking data structures. for (DN_ForItCArray(it, DN_Arena, tls->arenas)) { DN_Arena *arena = it.data; - switch (DN_CAST(DN_OSTLSArena) it.index) { - default: *arena = DN_Arena_FromVMem(reserve, commit, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); break; - case DN_OSTLSArena_ErrorSink: *arena = DN_Arena_FromVMem(err_sink_reserve, err_sink_commit, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); break; + switch (DN_Cast(DN_OSTLSArena) it.index) { + default: *arena = DN_ArenaFromVMem(reserve, commit, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); break; + case DN_OSTLSArena_ErrorSink: *arena = DN_ArenaFromVMem(err_sink_reserve, err_sink_commit, DN_ArenaFlags_AllocCanLeak | DN_ArenaFlags_NoAllocTrack); break; case DN_OSTLSArena_Count: DN_InvalidCodePath; break; } } @@ -4583,7 +4547,7 @@ DN_API void DN_OS_TLSDeinit(DN_OSTLS *tls) tls->err_sink = {}; tls->arena_stack_index = {}; for (DN_ForItCArray(it, DN_Arena, tls->arenas)) - DN_Arena_Deinit(it.data); + DN_ArenaDeinit(it.data); } DN_THREAD_LOCAL DN_OSTLS *g_dn_curr_thread_tls; @@ -4691,22 +4655,22 @@ DN_API DN_OSErrSink *DN_OS_ErrSinkBegin_(DN_OSErrSinkMode mode, DN_CallSite call DN_OSTLS *tls = DN_OS_TLSGet(); DN_OSErrSink *err = &tls->err_sink; DN_OSErrSink *result = err; - DN_USize arena_pos = DN_Arena_Pos(result->arena); + DN_USize arena_pos = DN_ArenaPos(result->arena); if (tls->err_sink.stack_size == DN_ArrayCountU(err->stack)) { - DN_Str8Builder builder = DN_Str8Builder_FromTLS(); + DN_Str8Builder builder = DN_Str8BuilderFromTLS(); DN_USize counter = 0; for (DN_ForItSize(it, DN_OSErrSinkNode, err->stack, err->stack_size)) { DN_MSVC_WARNING_PUSH - DN_MSVC_WARNING_DISABLE(6284) // Object passed as _Param_(4) when a string is required in call to 'DN_Str8Builder_AppendF' Actual type: 'struct DN_Str8'. - DN_Str8Builder_AppendF(&builder, " [%04zu] %S:%u %S\n", counter++, it.data->call_site.file, it.data->call_site.line, it.data->call_site.function); + DN_MSVC_WARNING_DISABLE(6284) // Object passed as _Param_(4) when a string is required in call to 'DN_Str8BuilderAppendF' Actual type: 'struct DN_Str8'. + DN_Str8BuilderAppendF(&builder, " [%04zu] %S:%u %S\n", counter++, it.data->call_site.file, it.data->call_site.line, it.data->call_site.function); DN_MSVC_WARNING_POP } DN_MSVC_WARNING_PUSH DN_MSVC_WARNING_DISABLE(6284) // Object passed as _Param_(6) when a string is required in call to 'DN_LOG_EmitFromType' Actual type: 'struct DN_Str8'. DN_AssertF(tls->err_sink.stack_size < DN_ArrayCountU(err->stack), - "Error sink has run out of error scopes, potential leak. Scopes were\n%S", DN_Str8Builder_BuildFromTLS(&builder)); + "Error sink has run out of error scopes, potential leak. Scopes were\n%S", DN_Str8BuilderBuildFromTLS(&builder)); DN_MSVC_WARNING_POP } @@ -4718,7 +4682,7 @@ DN_API DN_OSErrSink *DN_OS_ErrSinkBegin_(DN_OSErrSinkMode mode, DN_CallSite call // NOTE: Handle allocation error if (!DN_Check(node && node->msg_sentinel)) { - DN_Arena_PopTo(result->arena, arena_pos); + DN_ArenaPopTo(result->arena, arena_pos); node->msg_sentinel = nullptr; tls->err_sink.stack_size--; } @@ -4749,8 +4713,8 @@ DN_API DN_OSErrSinkMsg *DN_OS_ErrSinkEnd(DN_Arena *arena, DN_OSErrSink *err) DN_OSErrSinkNode *node = err->stack + (err->stack_size - 1); DN_OSErrSinkMsg *prev = nullptr; for (DN_OSErrSinkMsg *it = node->msg_sentinel->next; it != node->msg_sentinel; it = it->next) { - DN_OSErrSinkMsg *entry = DN_Arena_New(arena, DN_OSErrSinkMsg, DN_ZeroMem_Yes); - entry->msg = DN_Str8_FromStr8(arena, it->msg); + DN_OSErrSinkMsg *entry = DN_ArenaNew(arena, DN_OSErrSinkMsg, DN_ZMem_Yes); + entry->msg = DN_Str8FromStr8Arena(arena, it->msg); entry->call_site = it->call_site; entry->error_code = it->error_code; if (!result) @@ -4762,36 +4726,36 @@ DN_API DN_OSErrSinkMsg *DN_OS_ErrSinkEnd(DN_Arena *arena, DN_OSErrSink *err) // NOTE: Deallocate all the memory for this scope err->stack_size--; - DN_Arena_PopTo(err->arena, node->arena_pos); + DN_ArenaPopTo(err->arena, node->arena_pos); return result; } -static void DN_OS_ErrSinkAddMsgToStr8Builder_(DN_Str8Builder *builder, DN_OSErrSinkMsg *msg, DN_OSErrSinkMsg *end) +static void DN_OS_ErrSinkAddMsgToStr8Builder(DN_Str8Builder *builder, DN_OSErrSinkMsg *msg, DN_OSErrSinkMsg *end) { if (msg == end) // NOTE: No error messages to add return; if (msg->next == end) { DN_OSErrSinkMsg *it = msg; - DN_Str8 file_name = DN_Str8_FileNameFromPath(it->call_site.file); - DN_Str8Builder_AppendF(builder, + DN_Str8 file_name = DN_Str8FileNameFromPath(it->call_site.file); + DN_Str8BuilderAppendF(builder, "%.*s:%05I32u:%.*s %.*s", - DN_STR_FMT(file_name), + DN_Str8PrintFmt(file_name), it->call_site.line, - DN_STR_FMT(it->call_site.function), - DN_STR_FMT(it->msg)); + DN_Str8PrintFmt(it->call_site.function), + DN_Str8PrintFmt(it->msg)); } else { // NOTE: More than one message for (DN_OSErrSinkMsg *it = msg; it != end; it = it->next) { - DN_Str8 file_name = DN_Str8_FileNameFromPath(it->call_site.file); - DN_Str8Builder_AppendF(builder, + DN_Str8 file_name = DN_Str8FileNameFromPath(it->call_site.file); + DN_Str8BuilderAppendF(builder, "%s - %.*s:%05I32u:%.*s%s%.*s", it == msg ? "" : "\n", - DN_STR_FMT(file_name), + DN_Str8PrintFmt(file_name), it->call_site.line, - DN_STR_FMT(it->call_site.function), - DN_Str8_HasData(it->msg) ? " " : "", - DN_STR_FMT(it->msg)); + DN_Str8PrintFmt(it->call_site.function), + it->msg.size ? " " : "", + DN_Str8PrintFmt(it->msg)); } } } @@ -4808,16 +4772,16 @@ DN_API DN_Str8 DN_OS_ErrSinkEndStr8(DN_Arena *arena, DN_OSErrSink *err) // NOTE: Walk the list and allocate it onto the user's arena DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(arena); - DN_Str8Builder builder = DN_Str8Builder_FromTLS(); + DN_Str8Builder builder = DN_Str8BuilderFromTLS(); DN_OSErrSinkNode *node = err->stack + (err->stack_size - 1); - DN_OS_ErrSinkAddMsgToStr8Builder_(&builder, node->msg_sentinel->next, node->msg_sentinel); + DN_OS_ErrSinkAddMsgToStr8Builder(&builder, node->msg_sentinel->next, node->msg_sentinel); // NOTE: Deallocate all the memory for this scope err->stack_size--; DN_U64 arena_pos = node->arena_pos; - DN_Arena_PopTo(err->arena, arena_pos); + DN_ArenaPopTo(err->arena, arena_pos); - result = DN_Str8Builder_Build(&builder, arena); + result = DN_Str8BuilderBuild(&builder, arena); return result; } @@ -4838,20 +4802,20 @@ DN_API bool DN_OS_ErrSinkEndAndLogError_(DN_OSErrSink *err, DN_CallSite call_sit if (!msg) return false; - DN_Str8Builder builder = DN_Str8Builder_FromTLS(); - if (DN_Str8_HasData(err_msg)) { - DN_Str8Builder_AppendRef(&builder, err_msg); - DN_Str8Builder_AppendRef(&builder, DN_STR8(":")); + DN_Str8Builder builder = DN_Str8BuilderFromTLS(); + if (err_msg.size) { + DN_Str8BuilderAppendRef(&builder, err_msg); + DN_Str8BuilderAppendRef(&builder, DN_Str8Lit(":")); } else { - DN_Str8Builder_AppendRef(&builder, DN_STR8("Error(s) encountered:")); + DN_Str8BuilderAppendRef(&builder, DN_Str8Lit("Error(s) encountered:")); } if (msg->next) // NOTE: More than 1 message - DN_Str8Builder_AppendRef(&builder, DN_STR8("\n")); - DN_OS_ErrSinkAddMsgToStr8Builder_(&builder, msg, nullptr); + DN_Str8BuilderAppendRef(&builder, DN_Str8Lit("\n")); + DN_OS_ErrSinkAddMsgToStr8Builder(&builder, msg, nullptr); - DN_Str8 log = DN_Str8Builder_BuildFromTLS(&builder); - DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Error), call_site, "%.*s", DN_STR_FMT(log)); + DN_Str8 log = DN_Str8BuilderBuildFromTLS(&builder); + DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Error), call_site, "%.*s", DN_Str8PrintFmt(log)); if (mode == DN_OSErrSinkMode_DebugBreakOnEndAndLog) DN_DebugBreak; @@ -4861,7 +4825,7 @@ DN_API bool DN_OS_ErrSinkEndAndLogError_(DN_OSErrSink *err, DN_CallSite call_sit DN_API bool DN_OS_ErrSinkEndAndLogErrorFV_(DN_OSErrSink *err, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, va_list args) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 log = DN_Str8_FromFV(tmem.arena, fmt, args); + DN_Str8 log = DN_Str8FromFmtVArena(tmem.arena, fmt, args); bool result = DN_OS_ErrSinkEndAndLogError_(err, call_site, log); return result; } @@ -4871,7 +4835,7 @@ DN_API bool DN_OS_ErrSinkEndAndLogErrorF_(DN_OSErrSink *err, DN_CallSite call_si va_list args; va_start(args, fmt); DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 log = DN_Str8_FromFV(tmem.arena, fmt, args); + DN_Str8 log = DN_Str8FromFmtVArena(tmem.arena, fmt, args); bool result = DN_OS_ErrSinkEndAndLogError_(err, call_site, log); va_end(args); return result; @@ -4901,9 +4865,9 @@ DN_API void DN_OS_ErrSinkAppendFV_(DN_OSErrSink *err, DN_U32 error_code, DN_FMT_ DN_OSErrSinkNode *node = err->stack + (err->stack_size - 1); DN_AssertF(node, "Error sink must be begun by calling 'Begin' before using this function."); - DN_OSErrSinkMsg *msg = DN_Arena_New(err->arena, DN_OSErrSinkMsg, DN_ZeroMem_Yes); + DN_OSErrSinkMsg *msg = DN_ArenaNew(err->arena, DN_OSErrSinkMsg, DN_ZMem_Yes); if (DN_Check(msg)) { - msg->msg = DN_Str8_FromFV(err->arena, fmt, args); + msg->msg = DN_Str8FromFmtVArena(err->arena, fmt, args); msg->error_code = error_code; msg->call_site = DN_OS_TLSGet()->call_site; DN_DLList_Prepend(node->msg_sentinel, msg); @@ -4939,7 +4903,7 @@ static DN_OSCore *g_dn_os_core_; static void DN_OS_LOGEmitFromTypeTypeFV_(DN_LOGTypeParam type, void *user_data, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, va_list args) { DN_Assert(user_data); - DN_OSCore *core = DN_CAST(DN_OSCore *)user_data; + DN_OSCore *core = DN_Cast(DN_OSCore *)user_data; // NOTE: Open log file for appending if requested //////////////////////////////////////////////// DN_TicketMutex_Begin(&core->log_file_mutex); @@ -4997,17 +4961,17 @@ static void DN_OS_LOGEmitFromTypeTypeFV_(DN_LOGTypeParam type, void *user_data, va_copy(args_copy, args); DN_TicketMutex_Begin(&core->log_file_mutex); { - DN_OS_FileWrite(&core->log_file, DN_Str8_Init(prefix_buffer, prefix_size.size), nullptr); - DN_OS_FileWriteF(&core->log_file, nullptr, "%*s ", DN_CAST(int)prefix_size.padding, ""); + DN_OS_FileWrite(&core->log_file, DN_Str8FromPtr(prefix_buffer, prefix_size.size), nullptr); + DN_OS_FileWriteF(&core->log_file, nullptr, "%*s ", DN_Cast(int)prefix_size.padding, ""); DN_OS_FileWriteFV(&core->log_file, nullptr, fmt, args_copy); - DN_OS_FileWrite(&core->log_file, DN_STR8("\n"), nullptr); + DN_OS_FileWrite(&core->log_file, DN_Str8Lit("\n"), nullptr); } DN_TicketMutex_End(&core->log_file_mutex); va_end(args_copy); DN_OSPrintDest dest = (type.is_u32_enum && type.u32 == DN_LOGType_Error) ? DN_OSPrintDest_Err : DN_OSPrintDest_Out; - DN_OS_Print(dest, DN_Str8_Init(prefix_buffer, prefix_size.size)); - DN_OS_PrintF(dest, "%*s ", DN_CAST(int)prefix_size.padding, ""); + DN_OS_Print(dest, DN_Str8FromPtr(prefix_buffer, prefix_size.size)); + DN_OS_PrintF(dest, "%*s ", DN_Cast(int)prefix_size.padding, ""); DN_OS_PrintLnFV(dest, fmt, args); } @@ -5040,24 +5004,24 @@ DN_API void DN_OS_Init(DN_OSCore *os, DN_OSInitArgs *args) { #if defined(DN_PLATFORM_EMSCRIPTEN) - os->arena = DN_Arena_FromHeap(DN_Megabytes(1), DN_ArenaFlags_NoAllocTrack); + os->arena = DN_ArenaFromHeap(DN_Megabytes(1), DN_ArenaFlags_NoAllocTrack); #else - os->arena = DN_Arena_FromVMem(DN_Megabytes(1), DN_Kilobytes(4), DN_ArenaFlags_NoAllocTrack); + os->arena = DN_ArenaFromVMem(DN_Megabytes(1), DN_Kilobytes(4), DN_ArenaFlags_NoAllocTrack); #endif #if defined(DN_PLATFORM_WIN32) - os->platform_context = DN_Arena_New(&os->arena, DN_W32Core, DN_ZeroMem_Yes); + os->platform_context = DN_ArenaNew(&os->arena, DN_W32Core, DN_ZMem_Yes); #elif defined(DN_PLATFORM_POSIX) || defined(DN_PLATFORM_EMSCRIPTEN) - os->platform_context = DN_Arena_New(&os->arena, DN_POSIXCore, DN_ZeroMem_Yes); + os->platform_context = DN_ArenaNew(&os->arena, DN_POSIXCore, DN_ZMem_Yes); #endif #if defined(DN_PLATFORM_WIN32) - DN_W32Core *w32 = DN_CAST(DN_W32Core *) os->platform_context; + DN_W32Core *w32 = DN_Cast(DN_W32Core *) os->platform_context; InitializeCriticalSection(&w32->sync_primitive_free_list_mutex); QueryPerformanceFrequency(&w32->qpc_frequency); HMODULE module = LoadLibraryA("kernel32.dll"); - w32->set_thread_description = DN_CAST(DN_W32SetThreadDescriptionFunc *) GetProcAddress(module, "SetThreadDescription"); + w32->set_thread_description = DN_Cast(DN_W32SetThreadDescriptionFunc *) GetProcAddress(module, "SetThreadDescription"); FreeLibrary(module); // NOTE: win32 bcrypt @@ -5068,7 +5032,7 @@ DN_API void DN_OS_Init(DN_OSCore *os, DN_OSInitArgs *args) else DN_LOG_ErrorF("Failed to initialise Windows secure random number generator, error: %d", init_status); #else - DN_Posix_Init(DN_CAST(DN_POSIXCore *)os->platform_context); + DN_Posix_Init(DN_Cast(DN_POSIXCore *)os->platform_context); #endif } @@ -5089,7 +5053,7 @@ DN_API void DN_OS_Init(DN_OSCore *os, DN_OSInitArgs *args) DN_OS_TLSSetCurrentThreadTLS(&os->tls); os->cpu_report = DN_CPUGetReport(); - #define DN_CPU_FEAT_XENTRY(label) g_dn_cpu_feature_decl[DN_CPUFeature_##label] = {DN_CPUFeature_##label, DN_STR8(#label)}; + #define DN_CPU_FEAT_XENTRY(label) g_dn_cpu_feature_decl[DN_CPUFeature_##label] = {DN_CPUFeature_##label, DN_Str8Lit(#label)}; DN_CPU_FEAT_XMACRO #undef DN_CPU_FEAT_XENTRY DN_Assert(g_dn_os_core_); @@ -5108,7 +5072,7 @@ DN_API void DN_OS_DumpThreadContextArenaStat(DN_Str8 file_path) FILE *file = nullptr; fopen_s(&file, file_path.data, "a+b"); if (file) { - DN_LOG_ErrorF("Failed to dump thread context arenas [file=%.*s]", DN_STR_FMT(file_path)); + DN_LOG_ErrorF("Failed to dump thread context arenas [file=%.*s]", DN_Str8PrintFmt(file_path)); return; } @@ -5149,29 +5113,56 @@ DN_API void DN_OS_DumpThreadContextArenaStat(DN_Str8 file_path) stat.blocks_hwm = DN_Max(stat.blocks_hwm, current->blocks_hwm); } - DN_ArenaStatStr stats_string = DN_Arena_StatStr(&stat); + DN_ArenaStatStr stats_string = DN_ArenaStatStr(&stat); fprintf(file, " [ALL] CURR %.*s\n", stats_string.size, stats_string.data); } // NOTE: Print individual thread arena data for (DN_USize index = 0; index < stats_size; index++) { DN_ArenaStat const *current = stats + index; - DN_ArenaStatStr current_string = DN_Arena_StatStr(current); - fprintf(file, " [%03d] CURR %.*s\n", DN_CAST(int) index, current_string.size, current_string.data); + DN_ArenaStatStr current_string = DN_ArenaStatStr(current); + fprintf(file, " [%03d] CURR %.*s\n", DN_Cast(int) index, current_string.size, current_string.data); } fclose(file); - DN_LOG_InfoF("Dumped thread context arenas [file=%.*s]", DN_STR_FMT(file_path)); + DN_LOG_InfoF("Dumped thread context arenas [file=%.*s]", DN_Str8PrintFmt(file_path)); #else (void)file_path; #endif // #if defined(DN_DEBUG_THREAD_CONTEXT) } +DN_API DN_Str8 DN_OS_BytesFromHexPtrArenaFrame(void const *hex, DN_USize hex_count) +{ + DN_Arena *frame_arena = DN_OS_TLSFrameArena(); + DN_Str8 result = DN_BytesFromHexPtrArena(hex, hex_count, frame_arena); + return result; +} + +DN_API DN_Str8 DN_OS_BytesFromHexStr8ArenaFrame(DN_Str8 hex) +{ + DN_Str8 result = DN_OS_BytesFromHexPtrArenaFrame(hex.data, hex.size); + return result; +} + +DN_API DN_Str8 DN_OS_HexFromBytesPtrArenaFrame(void const *bytes, DN_USize bytes_count) +{ + DN_Arena *frame_arena = DN_OS_TLSFrameArena(); + DN_Str8 result = DN_HexFromBytesPtrArena(bytes, bytes_count, frame_arena); + return result; +} + +DN_API DN_Str8 DN_OS_HexFromBytesPtrArenaTLS(void const *bytes, DN_USize bytes_count) +{ + DN_Arena *tls_arena = DN_OS_TLSArena(); + DN_Str8 result = DN_HexFromBytesPtrArena(bytes, bytes_count, tls_arena); + return result; +} + // NOTE: Date ////////////////////////////////////////////////////////////////////////////////////// DN_API DN_OSDateTimeStr8 DN_OS_DateLocalTimeStr8(DN_OSDateTime time, char date_separator, char hms_separator) { DN_OSDateTimeStr8 result = {}; - result.hms_size = DN_CAST(uint8_t) DN_SNPrintF(result.hms, + result.hms_size = DN_Cast(uint8_t) DN_SNPrintF(result.hms, DN_ArrayCountI(result.hms), "%02hhu%c%02hhu%c%02hhu", time.hour, @@ -5180,7 +5171,7 @@ DN_API DN_OSDateTimeStr8 DN_OS_DateLocalTimeStr8(DN_OSDateTime time, char date_s hms_separator, time.seconds); - result.date_size = DN_CAST(uint8_t) DN_SNPrintF(result.date, + result.date_size = DN_Cast(uint8_t) DN_SNPrintF(result.date, DN_ArrayCountI(result.date), "%hu%c%02hhu%c%02hhu", time.year, @@ -5226,9 +5217,9 @@ DN_API DN_Str8 DN_OS_EXEDir(DN_Arena *arena) return result; DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena); DN_Str8 exe_path = DN_OS_EXEPath(tmem.arena); - DN_Str8 separators[] = {DN_STR8("/"), DN_STR8("\\")}; - DN_Str8BSplitResult split = DN_Str8_BSplitLastArray(exe_path, separators, DN_ArrayCountU(separators)); - result = DN_Str8_FromStr8(arena, split.lhs); + DN_Str8 separators[] = {DN_Str8Lit("/"), DN_Str8Lit("\\")}; + DN_Str8BSplitResult split = DN_Str8BSplitLastArray(exe_path, separators, DN_ArrayCountU(separators)); + result = DN_Str8FromStr8Arena(arena, split.lhs); return result; } @@ -5237,7 +5228,7 @@ DN_API DN_F64 DN_OS_PerfCounterS(uint64_t begin, uint64_t end) { uint64_t frequency = DN_OS_PerfCounterFrequency(); uint64_t ticks = end - begin; - DN_F64 result = ticks / DN_CAST(DN_F64) frequency; + DN_F64 result = ticks / DN_Cast(DN_F64) frequency; return result; } @@ -5245,7 +5236,7 @@ DN_API DN_F64 DN_OS_PerfCounterMs(uint64_t begin, uint64_t end) { uint64_t frequency = DN_OS_PerfCounterFrequency(); uint64_t ticks = end - begin; - DN_F64 result = (ticks * 1'000) / DN_CAST(DN_F64) frequency; + DN_F64 result = (ticks * 1'000) / DN_Cast(DN_F64) frequency; return result; } @@ -5253,7 +5244,7 @@ DN_API DN_F64 DN_OS_PerfCounterUs(uint64_t begin, uint64_t end) { uint64_t frequency = DN_OS_PerfCounterFrequency(); uint64_t ticks = end - begin; - DN_F64 result = (ticks * 1'000'000) / DN_CAST(DN_F64) frequency; + DN_F64 result = (ticks * 1'000'000) / DN_Cast(DN_F64) frequency; return result; } @@ -5261,7 +5252,7 @@ DN_API DN_F64 DN_OS_PerfCounterNs(uint64_t begin, uint64_t end) { uint64_t frequency = DN_OS_PerfCounterFrequency(); uint64_t ticks = end - begin; - DN_F64 result = (ticks * 1'000'000'000) / DN_CAST(DN_F64) frequency; + DN_F64 result = (ticks * 1'000'000'000) / DN_Cast(DN_F64) frequency; return result; } @@ -5341,9 +5332,9 @@ struct DN_OSFileWriteChunker_ static char *DN_OS_FileWriteChunker_(const char *buf, void *user, int len) { - DN_OSFileWriteChunker_ *chunker = DN_CAST(DN_OSFileWriteChunker_ *)user; + DN_OSFileWriteChunker_ *chunker = DN_Cast(DN_OSFileWriteChunker_ *)user; chunker->success = DN_OS_FileWritePtr(chunker->file, buf, len, chunker->err); - char *result = chunker->success ? DN_CAST(char *) buf : nullptr; + char *result = chunker->success ? DN_Cast(char *) buf : nullptr; return result; } @@ -5378,24 +5369,24 @@ DN_API DN_Str8 DN_OS_FileReadAll(DN_Allocator alloc_type, void *allocator, DN_St DN_Str8 result = {}; DN_OSPathInfo path_info = DN_OS_PathInfo(path); if (!path_info.exists) { - DN_OS_ErrSinkAppendF(err, 1, "File does not exist/could not be queried for reading '%.*s'", DN_STR_FMT(path)); + DN_OS_ErrSinkAppendF(err, 1, "File does not exist/could not be queried for reading '%.*s'", DN_Str8PrintFmt(path)); return result; } // NOTE: Allocate DN_ArenaTempMem arena_tmp = {}; if (alloc_type == DN_Allocator_Arena) { - DN_Arena *arena = DN_CAST(DN_Arena *) allocator; - arena_tmp = DN_Arena_TempMemBegin(arena); - result = DN_Str8_Alloc(arena, path_info.size, DN_ZeroMem_No); + DN_Arena *arena = DN_Cast(DN_Arena *) allocator; + arena_tmp = DN_ArenaTempMemBegin(arena); + result = DN_Str8FromArena(arena, path_info.size, DN_ZMem_No); } else { - DN_Pool *pool = DN_CAST(DN_Pool *) allocator; - result = DN_Str8_AllocPool(pool, path_info.size); + DN_Pool *pool = DN_Cast(DN_Pool *) allocator; + result = DN_Str8FromPool(pool, path_info.size); } if (!result.data) { - DN_CVTU64Bytes bytes_str = DN_CVT_BytesFromU64Auto(path_info.size); - DN_OS_ErrSinkAppendF(err, 1 /*err_code*/, "Failed to allocate %.1f %.*s for reading file '%.*s'", bytes_str.bytes, DN_STR_FMT(bytes_str.suffix), DN_STR_FMT(path)); + DN_Str8x32 bytes_str = DN_ByteCountStr8x32(path_info.size); + DN_OS_ErrSinkAppendF(err, 1 /*err_code*/, "Failed to allocate %.*s for reading file '%.*s'", DN_Str8PrintFmt(bytes_str), DN_Str8PrintFmt(path)); return result; } @@ -5404,10 +5395,10 @@ DN_API DN_Str8 DN_OS_FileReadAll(DN_Allocator alloc_type, void *allocator, DN_St DN_OSFileRead read = DN_OS_FileRead(&file, result.data, result.size, err); if (file.error || !read.success) { if (alloc_type == DN_Allocator_Arena) { - DN_Arena_TempMemEnd(arena_tmp); + DN_ArenaTempMemEnd(arena_tmp); } else { - DN_Pool *pool = DN_CAST(DN_Pool *) allocator; - DN_Pool_Dealloc(pool, result.data); + DN_Pool *pool = DN_Cast(DN_Pool *) allocator; + DN_PoolDealloc(pool, result.data); } result = {}; } @@ -5445,7 +5436,7 @@ DN_API bool DN_OS_FileWriteAll(DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *error DN_API bool DN_OS_FileWriteAllFV(DN_Str8 file_path, DN_OSErrSink *error, DN_FMT_ATTRIB char const *fmt, va_list args) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 buffer = DN_Str8_FromFV(tmem.arena, fmt, args); + DN_Str8 buffer = DN_Str8FromFmtVArena(tmem.arena, fmt, args); bool result = DN_OS_FileWriteAll(file_path, buffer, error); return result; } @@ -5462,7 +5453,7 @@ DN_API bool DN_OS_FileWriteAllF(DN_Str8 file_path, DN_OSErrSink *error, DN_FMT_A DN_API bool DN_OS_FileWriteAllSafe(DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *error) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 tmp_path = DN_Str8_FromF(tmem.arena, "%.*s.tmp", DN_STR_FMT(path)); + DN_Str8 tmp_path = DN_Str8FromFmtArena(tmem.arena, "%.*s.tmp", DN_Str8PrintFmt(path)); if (!DN_OS_FileWriteAll(tmp_path, buffer, error)) return false; if (!DN_OS_FileCopy(tmp_path, path, true /*overwrite*/, error)) @@ -5475,7 +5466,7 @@ DN_API bool DN_OS_FileWriteAllSafe(DN_Str8 path, DN_Str8 buffer, DN_OSErrSink *e DN_API bool DN_OS_FileWriteAllSafeFV(DN_Str8 path, DN_OSErrSink *error, DN_FMT_ATTRIB char const *fmt, va_list args) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 buffer = DN_Str8_FromFV(tmem.arena, fmt, args); + DN_Str8 buffer = DN_Str8FromFmtVArena(tmem.arena, fmt, args); bool result = DN_OS_FileWriteAllSafe(path, buffer, error); return result; } @@ -5490,26 +5481,26 @@ DN_API bool DN_OS_FileWriteAllSafeF(DN_Str8 path, DN_OSErrSink *error, DN_FMT_AT DN_API bool DN_OS_PathAddRef(DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path) { - if (!arena || !fs_path || !DN_Str8_HasData(path)) + if (!arena || !fs_path || path.size == 0) return false; if (path.size <= 0) return true; DN_Str8 const delimiter_array[] = { - DN_STR8("\\"), - DN_STR8("/")}; + DN_Str8Lit("\\"), + DN_Str8Lit("/")}; if (fs_path->links_size == 0) fs_path->has_prefix_path_separator = (path.data[0] == '/'); for (;;) { - DN_Str8BSplitResult delimiter = DN_Str8_BSplitArray(path, delimiter_array, DN_ArrayCountU(delimiter_array)); - for (; delimiter.lhs.data; delimiter = DN_Str8_BSplitArray(delimiter.rhs, delimiter_array, DN_ArrayCountU(delimiter_array))) { + DN_Str8BSplitResult delimiter = DN_Str8BSplitArray(path, delimiter_array, DN_ArrayCountU(delimiter_array)); + for (; delimiter.lhs.data; delimiter = DN_Str8BSplitArray(delimiter.rhs, delimiter_array, DN_ArrayCountU(delimiter_array))) { if (delimiter.lhs.size <= 0) continue; - DN_OSPathLink *link = DN_Arena_New(arena, DN_OSPathLink, DN_ZeroMem_Yes); + DN_OSPathLink *link = DN_ArenaNew(arena, DN_OSPathLink, DN_ZMem_Yes); if (!link) return false; @@ -5545,8 +5536,8 @@ DN_API bool DN_OS_PathAddRefFrame(DN_OSPath *fs_path, DN_Str8 path) DN_API bool DN_OS_PathAdd(DN_Arena *arena, DN_OSPath *fs_path, DN_Str8 path) { - DN_Str8 copy = DN_Str8_FromStr8(arena, path); - bool result = DN_Str8_HasData(copy) ? true : DN_OS_PathAddRef(arena, fs_path, copy); + DN_Str8 copy = DN_Str8FromStr8Arena(arena, path); + bool result = copy.size ? true : DN_OS_PathAddRef(arena, fs_path, copy); return result; } @@ -5554,7 +5545,7 @@ DN_API bool DN_OS_PathAddF(DN_Arena *arena, DN_OSPath *fs_path, DN_FMT_ATTRIB ch { va_list args; va_start(args, fmt); - DN_Str8 path = DN_Str8_FromFV(arena, fmt, args); + DN_Str8 path = DN_Str8FromFmtVArena(arena, fmt, args); va_end(args); bool result = DN_OS_PathAddRef(arena, fs_path, path); return result; @@ -5594,7 +5585,7 @@ DN_API DN_Str8 DN_OS_PathToF(DN_Arena *arena, DN_Str8 path_separator, DN_FMT_ATT DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena); va_list args; va_start(args, fmt); - DN_Str8 path = DN_Str8_FromFV(tmem.arena, fmt, args); + DN_Str8 path = DN_Str8FromFmtVArena(tmem.arena, fmt, args); va_end(args); DN_Str8 result = DN_OS_PathTo(arena, path, path_separator); return result; @@ -5611,7 +5602,7 @@ DN_API DN_Str8 DN_OS_PathF(DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...) DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena); va_list args; va_start(args, fmt); - DN_Str8 path = DN_Str8_FromFV(tmem.arena, fmt, args); + DN_Str8 path = DN_Str8FromFmtVArena(tmem.arena, fmt, args); va_end(args); DN_Str8 result = DN_OS_Path(arena, path); return result; @@ -5625,7 +5616,7 @@ DN_API DN_Str8 DN_OS_PathBuildWithSeparator(DN_Arena *arena, DN_OSPath const *fs // NOTE: Each link except the last one needs the path separator appended to it, '/' or '\\' DN_USize string_size = (fs_path->has_prefix_path_separator ? path_separator.size : 0) + fs_path->string_size + ((fs_path->links_size - 1) * path_separator.size); - result = DN_Str8_Alloc(arena, string_size, DN_ZeroMem_No); + result = DN_Str8FromArena(arena, string_size, DN_ZMem_No); if (result.data) { char *dest = result.data; if (fs_path->has_prefix_path_separator) { @@ -5676,7 +5667,7 @@ DN_API DN_OSExecResult DN_OS_ExecOrAbort(DN_Slice cmd_line, DN_OSExecAr // NOTE: DN_OSThread /////////////////////////////////////////////////////////////////////////////// static void DN_OS_ThreadExecute_(void *user_context) { - DN_OSThread *thread = DN_CAST(DN_OSThread *) user_context; + DN_OSThread *thread = DN_Cast(DN_OSThread *) user_context; DN_OS_TLSInit(&thread->tls, thread->tls_init_args); DN_OS_TLSSetCurrentThreadTLS(&thread->tls); DN_OS_SemaphoreWait(&thread->init_semaphore, DN_OS_SEMAPHORE_INFINITE_TIMEOUT); @@ -5686,7 +5677,7 @@ static void DN_OS_ThreadExecute_(void *user_context) DN_API void DN_OS_ThreadSetName(DN_Str8 name) { DN_OSTLS *tls = DN_OS_TLSGet(); - tls->name_size = DN_CAST(uint8_t) DN_Min(name.size, sizeof(tls->name) - 1); + tls->name_size = DN_Cast(uint8_t) DN_Min(name.size, sizeof(tls->name) - 1); DN_Memcpy(tls->name, name.data, tls->name_size); tls->name[tls->name_size] = 0; @@ -5721,23 +5712,23 @@ DN_API DN_OSHttpResponse DN_OS_HttpRequest(DN_Arena *arena, DN_Str8 host, DN_Str // 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" -static void *DN_Arena_BasicAllocFromOSHeap(DN_USize size) +static void *DN_ArenaBasicAllocFromOSHeap(DN_USize size) { - void *result = DN_OS_MemAlloc(size, DN_ZeroMem_Yes); + void *result = DN_OS_MemAlloc(size, DN_ZMem_Yes); return result; } -DN_API DN_Arena DN_Arena_FromHeap(DN_U64 size, DN_ArenaFlags flags) +DN_API DN_Arena DN_ArenaFromHeap(DN_U64 size, DN_ArenaFlags flags) { DN_ArenaMemFuncs mem_funcs = {}; mem_funcs.type = DN_ArenaMemFuncType_Basic; - mem_funcs.basic_alloc = DN_Arena_BasicAllocFromOSHeap; + mem_funcs.basic_alloc = DN_ArenaBasicAllocFromOSHeap; mem_funcs.basic_dealloc = DN_OS_MemDealloc; - DN_Arena result = DN_Arena_FromMemFuncs(size, size, flags, mem_funcs); + DN_Arena result = DN_ArenaFromMemFuncs(size, size, flags, mem_funcs); return result; } -DN_API DN_Arena DN_Arena_FromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags) +DN_API DN_Arena DN_ArenaFromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags) { DN_ArenaMemFuncs mem_funcs = {}; mem_funcs.type = DN_ArenaMemFuncType_VMem; @@ -5745,7 +5736,7 @@ DN_API DN_Arena DN_Arena_FromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags f mem_funcs.vmem_reserve = DN_OS_MemReserve; mem_funcs.vmem_commit = DN_OS_MemCommit; mem_funcs.vmem_release = DN_OS_MemRelease; - DN_Arena result = DN_Arena_FromMemFuncs(reserve, commit, flags, mem_funcs); + DN_Arena result = DN_ArenaFromMemFuncs(reserve, commit, flags, mem_funcs); return result; } @@ -5774,7 +5765,7 @@ template DN_VArray DN_VArray_InitByteSize(DN_USize byte_size) { DN_VArray result = {}; - result.data = DN_CAST(T *) DN_OS_MemReserve(byte_size, DN_MemCommit_No, DN_MemPage_ReadWrite); + result.data = DN_Cast(T *) DN_OS_MemReserve(byte_size, DN_MemCommit_No, DN_MemPage_ReadWrite); if (result.data) result.max = byte_size / sizeof(T); return result; @@ -5832,7 +5823,7 @@ DN_Slice DN_VArray_Slice(DN_VArray const *array) template T *DN_VArray_AddArray(DN_VArray *array, T const *items, DN_USize count) { - T *result = DN_VArray_MakeArray(array, count, DN_ZeroMem_No); + T *result = DN_VArray_MakeArray(array, count, DN_ZMem_No); if (result) DN_Memcpy(result, items, count * sizeof(T)); return result; @@ -5853,7 +5844,7 @@ T *DN_VArray_Add(DN_VArray *array, T const &item) } template -T *DN_VArray_MakeArray(DN_VArray *array, DN_USize count, DN_ZeroMem zero_mem) +T *DN_VArray_MakeArray(DN_VArray *array, DN_USize count, DN_ZMem z_mem) { if (!DN_VArray_IsValid(array)) return nullptr; @@ -5867,15 +5858,15 @@ T *DN_VArray_MakeArray(DN_VArray *array, DN_USize count, DN_ZeroMem zero_mem) // TODO: Use placement new T *result = array->data + array->size; array->size += count; - if (zero_mem == DN_ZeroMem_Yes) + if (z_mem == DN_ZMem_Yes) DN_Memset(result, 0, count * sizeof(T)); return result; } template -T *DN_VArray_Make(DN_VArray *array, DN_ZeroMem zero_mem) +T *DN_VArray_Make(DN_VArray *array, DN_ZMem z_mem) { - T *result = DN_VArray_MakeArray(array, 1, zero_mem); + T *result = DN_VArray_MakeArray(array, 1, z_mem); return result; } @@ -5929,10 +5920,10 @@ DN_ArrayEraseResult DN_VArray_EraseRange(DN_VArray *array, DN_USize begin_ind } template -void DN_VArray_Clear(DN_VArray *array, DN_ZeroMem zero_mem) +void DN_VArray_Clear(DN_VArray *array, DN_ZMem z_mem) { if (array) { - if (zero_mem == DN_ZeroMem_Yes) + if (z_mem == DN_ZMem_Yes) DN_Memset(array->data, 0, array->size * sizeof(T)); array->size = 0; } @@ -6012,15 +6003,15 @@ DN_API void DN_OS_Print(DN_OSPrintDest dest, DN_Str8 string) } // NOTE: Write the string ////////////////////////////////////////////////////////////////////// - DN_Assert(string.size < DN_CAST(unsigned long) - 1); + DN_Assert(string.size < DN_Cast(unsigned long) - 1); unsigned long bytes_written = 0; (void)bytes_written; if (print_to_console) - WriteConsoleA(print_handle, string.data, DN_CAST(unsigned long) string.size, &bytes_written, nullptr); + WriteConsoleA(print_handle, string.data, DN_Cast(unsigned long) string.size, &bytes_written, nullptr); else - WriteFile(print_handle, string.data, DN_CAST(unsigned long) string.size, &bytes_written, nullptr); + WriteFile(print_handle, string.data, DN_Cast(unsigned long) string.size, &bytes_written, nullptr); #else - fprintf(dest == DN_OSPrintDest_Out ? stdout : stderr, "%.*s", DN_STR_FMT(string)); + fprintf(dest == DN_OSPrintDest_Out ? stdout : stderr, "%.*s", DN_Str8PrintFmt(string)); #endif } @@ -6046,20 +6037,20 @@ DN_API void DN_OS_PrintStyle(DN_OSPrintDest dest, DN_LOGStyle style, DN_Str8 str if (style.colour) DN_OS_Print(dest, DN_LOG_ColourEscapeCodeStr8FromRGB(DN_LOGColourType_Fg, style.r, style.g, style.b)); if (style.bold == DN_LOGBold_Yes) - DN_OS_Print(dest, DN_STR8(DN_LOG_BoldEscapeCode)); + DN_OS_Print(dest, DN_Str8Lit(DN_LOG_BoldEscapeCode)); DN_OS_Print(dest, string); if (style.colour || style.bold == DN_LOGBold_Yes) - DN_OS_Print(dest, DN_STR8(DN_LOG_ResetEscapeCode)); + DN_OS_Print(dest, DN_Str8Lit(DN_LOG_ResetEscapeCode)); } } static char *DN_OS_PrintVSPrintfChunker_(const char *buf, void *user, int len) { DN_Str8 string = {}; - string.data = DN_CAST(char *) buf; + string.data = DN_Cast(char *) buf; string.size = len; - DN_OSPrintDest dest = DN_CAST(DN_OSPrintDest) DN_CAST(uintptr_t) user; + DN_OSPrintDest dest = DN_Cast(DN_OSPrintDest) DN_Cast(uintptr_t) user; DN_OS_Print(dest, string); return (char *)buf; } @@ -6068,7 +6059,7 @@ DN_API void DN_OS_PrintFV(DN_OSPrintDest dest, DN_FMT_ATTRIB char const *fmt, va { char buffer[STB_SPRINTF_MIN]; STB_SPRINTF_DECORATE(vsprintfcb) - (DN_OS_PrintVSPrintfChunker_, DN_CAST(void *) DN_CAST(uintptr_t) dest, buffer, fmt, args); + (DN_OS_PrintVSPrintfChunker_, DN_Cast(void *) DN_Cast(uintptr_t) dest, buffer, fmt, args); } DN_API void DN_OS_PrintFVStyle(DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_ATTRIB char const *fmt, va_list args) @@ -6077,17 +6068,17 @@ DN_API void DN_OS_PrintFVStyle(DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_AT if (style.colour) DN_OS_Print(dest, DN_LOG_ColourEscapeCodeStr8FromRGB(DN_LOGColourType_Fg, style.r, style.g, style.b)); if (style.bold == DN_LOGBold_Yes) - DN_OS_Print(dest, DN_STR8(DN_LOG_BoldEscapeCode)); + DN_OS_Print(dest, DN_Str8Lit(DN_LOG_BoldEscapeCode)); DN_OS_PrintFV(dest, fmt, args); if (style.colour || style.bold == DN_LOGBold_Yes) - DN_OS_Print(dest, DN_STR8(DN_LOG_ResetEscapeCode)); + DN_OS_Print(dest, DN_Str8Lit(DN_LOG_ResetEscapeCode)); } } DN_API void DN_OS_PrintLn(DN_OSPrintDest dest, DN_Str8 string) { DN_OS_Print(dest, string); - DN_OS_Print(dest, DN_STR8("\n")); + DN_OS_Print(dest, DN_Str8Lit("\n")); } DN_API void DN_OS_PrintLnF(DN_OSPrintDest dest, DN_FMT_ATTRIB char const *fmt, ...) @@ -6101,13 +6092,13 @@ 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_OS_PrintFV(dest, fmt, args); - DN_OS_Print(dest, DN_STR8("\n")); + DN_OS_Print(dest, DN_Str8Lit("\n")); } DN_API void DN_OS_PrintLnStyle(DN_OSPrintDest dest, DN_LOGStyle style, DN_Str8 string) { DN_OS_PrintStyle(dest, style, string); - DN_OS_Print(dest, DN_STR8("\n")); + DN_OS_Print(dest, DN_Str8Lit("\n")); } DN_API void DN_OS_PrintLnFStyle(DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_ATTRIB char const *fmt, ...) @@ -6121,7 +6112,7 @@ DN_API void DN_OS_PrintLnFStyle(DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_A DN_API void DN_OS_PrintLnFVStyle(DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_ATTRIB char const *fmt, va_list args) { DN_OS_PrintFVStyle(dest, style, fmt, args); - DN_OS_Print(dest, DN_STR8("\n")); + DN_OS_Print(dest, DN_Str8Lit("\n")); } // DN: Single header generator inlined this file => #include "OS/dn_os_string.cpp" #define DN_OS_STRING_CPP @@ -6129,230 +6120,227 @@ DN_API void DN_OS_PrintLnFVStyle(DN_OSPrintDest dest, DN_LOGStyle style, DN_FMT_ // DN: Single header generator commented out this header => #include "../dn_base_inc.h" // DN: Single header generator commented out this header => #include "../dn_os_inc.h" -// NOTE: DN_Str8 /////////////////////////////////////////////////////////////////////////////////// -DN_API DN_Str8 DN_Str8_FromFrameF(DN_FMT_ATTRIB char const *fmt, ...) +// NOTE: DN_Str8 +DN_API DN_Str8 DN_Str8FromFmtArenaFrame(DN_FMT_ATTRIB char const *fmt, ...) { va_list args; va_start(args, fmt); - DN_Str8 result = DN_Str8_FromFV(DN_OS_TLSGet()->frame_arena, fmt, args); + DN_Arena *frame_arena = DN_OS_TLSGet()->frame_arena; + DN_Str8 result = DN_Str8FromFmtVArena(frame_arena, fmt, args); va_end(args); return result; } -DN_API DN_Str8 DN_Str8_FromFrameFV(DN_FMT_ATTRIB char const *fmt, va_list args) +DN_API DN_Str8 DN_Str8FromFmtVArenaFrame(DN_FMT_ATTRIB char const *fmt, va_list args) { - DN_Str8 result = DN_Str8_FromFV(DN_OS_TLSGet()->frame_arena, fmt, args); + DN_Arena *frame_arena = DN_OS_TLSGet()->frame_arena; + DN_Str8 result = DN_Str8FromFmtVArena(frame_arena, fmt, args); return result; } -DN_API DN_Str8 DN_Str8_FromFrame(DN_USize size, DN_ZeroMem zero_mem) +DN_API DN_Str8 DN_Str8FromArenaFrame(DN_USize size, DN_ZMem z_mem) { - DN_Str8 result = DN_Str8_Alloc(DN_OS_TLSGet()->frame_arena, size, zero_mem); + DN_Arena *frame_arena = DN_OS_TLSGet()->frame_arena; + DN_Str8 result = DN_Str8FromArena(frame_arena, size, z_mem); return result; } -DN_API DN_Str8 DN_Str8_FromHeapF(DN_FMT_ATTRIB char const *fmt, ...) +DN_API DN_Str8 DN_Str8FromHeapF(DN_FMT_ATTRIB char const *fmt, ...) { va_list args; va_start(args, fmt); - - DN_Str8 result = {}; - DN_USize size = DN_CStr8_FVSize(fmt, args); - if (size) { - result = DN_Str8_FromHeap(size, DN_ZeroMem_No); - if (DN_Str8_HasData(result)) - DN_VSNPrintF(result.data, DN_SaturateCastISizeToInt(size + 1 /*null-terminator*/), fmt, args); - } - + DN_USize size = DN_FmtVSize(fmt, args); + DN_Str8 result = DN_Str8FromHeap(size, DN_ZMem_No); + DN_VSNPrintF(result.data, DN_Cast(int)(result.size + 1), fmt, args); va_end(args); return result; } -DN_API DN_Str8 DN_Str8_FromHeap(DN_USize size, DN_ZeroMem zero_mem) +DN_API DN_Str8 DN_Str8FromHeap(DN_USize size, DN_ZMem z_mem) { DN_Str8 result = {}; - result.data = DN_CAST(char *)DN_OS_MemAlloc(size + 1, zero_mem); - if (result.data) - result.size = size; - result.data[result.size] = 0; + result.data = DN_Cast(char *)DN_OS_MemAlloc(size + 1, z_mem); + if (result.data) { + result.size = size; + result.data[result.size] = 0; + } return result; } -DN_API DN_Str8 DN_Str8_FromTLSFV(DN_FMT_ATTRIB char const *fmt, va_list args) +DN_API DN_Str8 DN_Str8FromTLSFV(DN_FMT_ATTRIB char const *fmt, va_list args) { - DN_Str8 result = DN_Str8_FromFV(DN_OS_TLSTopArena(), fmt, args); + DN_Str8 result = DN_Str8FromFmtVArena(DN_OS_TLSTopArena(), fmt, args); return result; } -DN_API DN_Str8 DN_Str8_FromTLSF(DN_FMT_ATTRIB char const *fmt, ...) +DN_API DN_Str8 DN_Str8FromTLSF(DN_FMT_ATTRIB char const *fmt, ...) { va_list args; va_start(args, fmt); - DN_Str8 result = DN_Str8_FromFV(DN_OS_TLSTopArena(), fmt, args); + DN_Str8 result = DN_Str8FromFmtVArena(DN_OS_TLSTopArena(), fmt, args); va_end(args); return result; } -DN_API DN_Str8 DN_Str8_FromTLS(DN_USize size, DN_ZeroMem zero_mem) +DN_API DN_Str8 DN_Str8FromTLS(DN_USize size, DN_ZMem z_mem) { - DN_Str8 result = DN_Str8_Alloc(DN_OS_TLSTopArena(), size, zero_mem); + DN_Str8 result = DN_Str8FromArena(DN_OS_TLSTopArena(), size, z_mem); return result; } -DN_API DN_Str8 DN_Str8_FromStr8Frame(DN_Str8 string) +DN_API DN_Str8 DN_Str8FromStr8Frame(DN_Str8 string) { - DN_Str8 result = DN_Str8_FromStr8(DN_OS_TLSGet()->frame_arena, string); + DN_Str8 result = DN_Str8FromStr8Arena(DN_OS_TLSGet()->frame_arena, string); return result; } -DN_API DN_Str8 DN_Str8_FromStr8TLS(DN_Str8 string) +DN_API DN_Str8 DN_Str8FromStr8TLS(DN_Str8 string) { - DN_Str8 result = DN_Str8_FromStr8(DN_OS_TLSTopArena(), string); + DN_Str8 result = DN_Str8FromStr8Arena(DN_OS_TLSTopArena(), string); return result; } -DN_API DN_Slice DN_Str8_SplitFromFrame(DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode) +DN_API DN_Str8SplitResult DN_Str8SplitFromFrame(DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode) { - DN_Slice result = DN_Str8_SplitAlloc(DN_OS_TLSGet()->frame_arena, string, delimiter, mode); + DN_Str8SplitResult result = DN_Str8SplitArena(DN_OS_TLSGet()->frame_arena, string, delimiter, mode); return result; } -DN_API DN_Slice DN_Str8_SplitFromTLS(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_Slice result = DN_Str8_SplitAlloc(DN_OS_TLSTopArena(), string, delimiter, mode); + DN_Str8SplitResult result = DN_Str8SplitArena(DN_OS_TLSTopArena(), string, delimiter, mode); return result; } -DN_API DN_Str8 DN_Str8_SegmentFromFrame(DN_Str8 src, DN_USize segment_size, char segment_char) +DN_API DN_Str8 DN_Str8SegmentFromFrame(DN_Str8 src, DN_USize segment_size, char segment_char) { - DN_Str8 result = DN_Str8_Segment(DN_OS_TLSGet()->frame_arena, src, segment_size, segment_char); + DN_Str8 result = DN_Str8Segment(DN_OS_TLSGet()->frame_arena, src, segment_size, segment_char); return result; } -DN_API DN_Str8 DN_Str8_SegmentFromTLS(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_Str8 result = DN_Str8_Segment(DN_OS_TLSTopArena(), src, segment_size, segment_char); + DN_Str8 result = DN_Str8Segment(DN_OS_TLSTopArena(), src, segment_size, segment_char); return result; } -DN_API DN_Str8 DN_Str8_ReverseSegmentFromFrame(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_Str8 result = DN_Str8_ReverseSegment(DN_OS_TLSGet()->frame_arena, src, segment_size, segment_char); + DN_Str8 result = DN_Str8ReverseSegment(DN_OS_TLSGet()->frame_arena, src, segment_size, segment_char); return result; } -DN_API DN_Str8 DN_Str8_ReverseSegmentFromTLS(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_Str8 result = DN_Str8_ReverseSegment(DN_OS_TLSTopArena(), src, segment_size, segment_char); + DN_Str8 result = DN_Str8ReverseSegment(DN_OS_TLSTopArena(), src, segment_size, segment_char); return result; } -DN_API DN_Str8 DN_Str8_AppendFFromFrame(DN_Str8 string, char const *fmt, ...) +DN_API DN_Str8 DN_Str8AppendFFromFrame(DN_Str8 string, char const *fmt, ...) { va_list args; va_start(args, fmt); - DN_Str8 result = DN_Str8_AppendFV(DN_OS_TLSGet()->frame_arena, string, fmt, args); + DN_Str8 result = DN_Str8AppendFV(DN_OS_TLSGet()->frame_arena, string, fmt, args); va_end(args); return result; } -DN_API DN_Str8 DN_Str8_AppendFFromTLS(DN_Str8 string, char const *fmt, ...) +DN_API DN_Str8 DN_Str8AppendFFromTLS(DN_Str8 string, char const *fmt, ...) { va_list args; va_start(args, fmt); - DN_Str8 result = DN_Str8_AppendFV(DN_OS_TLSTopArena(), string, fmt, args); + DN_Str8 result = DN_Str8AppendFV(DN_OS_TLSTopArena(), string, fmt, args); va_end(args); return result; } -DN_API DN_Str8 DN_Str8_FillFFromFrame(DN_USize count, char const *fmt, ...) +DN_API DN_Str8 DN_Str8FillFFromFrame(DN_USize count, char const *fmt, ...) { va_list args; va_start(args, fmt); - DN_Str8 result = DN_Str8_FillFV(DN_OS_TLSGet()->frame_arena, count, fmt, args); + DN_Str8 result = DN_Str8FillFV(DN_OS_TLSGet()->frame_arena, count, fmt, args); va_end(args); return result; } -DN_API DN_Str8 DN_Str8_FillFFromTLS(DN_USize count, char const *fmt, ...) +DN_API DN_Str8 DN_Str8FillFFromTLS(DN_USize count, char const *fmt, ...) { va_list args; va_start(args, fmt); - DN_Str8 result = DN_Str8_FillFV(DN_OS_TLSTopArena(), count, fmt, args); + DN_Str8 result = DN_Str8FillFV(DN_OS_TLSTopArena(), count, fmt, args); va_end(args); return result; } -DN_API DN_Str8DotTruncateResult DN_Str8_DotTruncateMiddleFromFrame(DN_Str8 str8, uint32_t side_size, DN_Str8 truncator) +DN_API DN_Str8TruncateResult DN_Str8TruncateMiddleArenaFrame(DN_Str8 str8, uint32_t side_size, DN_Str8 truncator) { - DN_Str8DotTruncateResult result = DN_Str8_DotTruncateMiddle(DN_OS_TLSGet()->frame_arena, str8, side_size, truncator); + DN_Str8TruncateResult result = DN_Str8TruncateMiddle(DN_OS_TLSGet()->frame_arena, str8, side_size, truncator); return result; } -DN_API DN_Str8DotTruncateResult DN_Str8_DotTruncateMiddleFromTLS(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_Str8DotTruncateResult result = DN_Str8_DotTruncateMiddle(DN_OS_TLSTopArena(), str8, side_size, truncator); + DN_Str8TruncateResult result = DN_Str8TruncateMiddle(DN_OS_TLSTopArena(), str8, side_size, truncator); return result; } - -DN_API DN_Str8 DN_Str8_PadNewLines(DN_Arena *arena, DN_Str8 src, DN_Str8 pad) +DN_API DN_Str8 DN_Str8PadNewLines(DN_Arena *arena, DN_Str8 src, DN_Str8 pad) { // TODO: Implement this without requiring TLS so it can go into base strings DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(arena); - DN_Str8Builder builder = DN_Str8Builder_FromTLS(); + DN_Str8Builder builder = DN_Str8BuilderFromTLS(); - DN_Str8BSplitResult split = DN_Str8_BSplit(src, DN_STR8("\n")); + DN_Str8BSplitResult split = DN_Str8BSplit(src, DN_Str8Lit("\n")); while (split.lhs.size) { - DN_Str8Builder_AppendRef(&builder, pad); - DN_Str8Builder_AppendRef(&builder, split.lhs); - split = DN_Str8_BSplit(split.rhs, DN_STR8("\n")); + DN_Str8BuilderAppendRef(&builder, pad); + DN_Str8BuilderAppendRef(&builder, split.lhs); + split = DN_Str8BSplit(split.rhs, DN_Str8Lit("\n")); if (split.lhs.size) - DN_Str8Builder_AppendRef(&builder, DN_STR8("\n")); + DN_Str8BuilderAppendRef(&builder, DN_Str8Lit("\n")); } - DN_Str8 result = DN_Str8Builder_Build(&builder, arena); + DN_Str8 result = DN_Str8BuilderBuild(&builder, arena); return result; } -DN_API DN_Str8 DN_Str8_PadNewLinesFromFrame(DN_Str8 src, DN_Str8 pad) +DN_API DN_Str8 DN_Str8PadNewLinesFromFrame(DN_Str8 src, DN_Str8 pad) { - DN_Str8 result = DN_Str8_PadNewLines(DN_OS_TLSGet()->frame_arena, src, pad); + DN_Str8 result = DN_Str8PadNewLines(DN_OS_TLSGet()->frame_arena, src, pad); return result; } -DN_API DN_Str8 DN_Str8_PadNewLinesFromTLS(DN_Str8 src, DN_Str8 pad) +DN_API DN_Str8 DN_Str8PadNewLinesFromTLS(DN_Str8 src, DN_Str8 pad) { - DN_Str8 result = DN_Str8_PadNewLines(DN_OS_TLSTopArena(), src, pad); + DN_Str8 result = DN_Str8PadNewLines(DN_OS_TLSTopArena(), src, pad); return result; } -DN_API DN_Str8 DN_Str8_UpperFromFrame(DN_Str8 string) +DN_API DN_Str8 DN_Str8UpperFromFrame(DN_Str8 string) { - DN_Str8 result = DN_Str8_Upper(DN_OS_TLSGet()->frame_arena, string); + DN_Str8 result = DN_Str8Upper(DN_OS_TLSGet()->frame_arena, string); return result; } -DN_API DN_Str8 DN_Str8_UpperFromTLS(DN_Str8 string) +DN_API DN_Str8 DN_Str8UpperFromTLS(DN_Str8 string) { - DN_Str8 result = DN_Str8_Upper(DN_OS_TLSTopArena(), string); + DN_Str8 result = DN_Str8Upper(DN_OS_TLSTopArena(), string); return result; } -DN_API DN_Str8 DN_Str8_LowerFromFrame(DN_Str8 string) +DN_API DN_Str8 DN_Str8LowerFromFrame(DN_Str8 string) { - DN_Str8 result = DN_Str8_Lower(DN_OS_TLSGet()->frame_arena, string); + DN_Str8 result = DN_Str8Lower(DN_OS_TLSGet()->frame_arena, string); return result; } -DN_API DN_Str8 DN_Str8_LowerFromTLS(DN_Str8 string) +DN_API DN_Str8 DN_Str8LowerFromTLS(DN_Str8 string) { - DN_Str8 result = DN_Str8_Lower(DN_OS_TLSTopArena(), string); + DN_Str8 result = DN_Str8Lower(DN_OS_TLSTopArena(), string); return result; } -DN_API DN_Str8 DN_Str8_Replace(DN_Str8 string, +DN_API DN_Str8 DN_Str8Replace(DN_Str8 string, DN_Str8 find, DN_Str8 replace, DN_USize start_index, @@ -6361,19 +6349,19 @@ DN_API DN_Str8 DN_Str8_Replace(DN_Str8 string, { // TODO: Implement this without requiring TLS so it can go into base strings DN_Str8 result = {}; - if (!DN_Str8_HasData(string) || !DN_Str8_HasData(find) || find.size > string.size || find.size == 0 || string.size == 0) { - result = DN_Str8_FromStr8(arena, string); + if (string.size == 0 || find.size == 0 || find.size > string.size || find.size == 0 || string.size == 0) { + result = DN_Str8FromStr8Arena(arena, string); return result; } DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena); - DN_Str8Builder string_builder = DN_Str8Builder_FromArena(tmem.arena); + DN_Str8Builder string_builder = DN_Str8BuilderFromArena(tmem.arena); DN_USize max = string.size - find.size; DN_USize head = start_index; for (DN_USize tail = head; tail <= max; tail++) { - DN_Str8 check = DN_Str8_Slice(string, tail, find.size); - if (!DN_Str8_Eq(check, find, eq_case)) + DN_Str8 check = DN_Str8Slice(string, tail, find.size); + if (!DN_Str8Eq(check, find, eq_case)) continue; if (start_index > 0 && string_builder.string_size == 0) { @@ -6381,43 +6369,43 @@ DN_API DN_Str8 DN_Str8_Replace(DN_Str8 string, // need to add the string up to the hint. We only do this if there's // a replacement action, otherwise we have a special case for no // replacements, where the entire string gets copied. - DN_Str8 slice = DN_Str8_Init(string.data, head); - DN_Str8Builder_AppendRef(&string_builder, slice); + DN_Str8 slice = DN_Str8FromPtr(string.data, head); + DN_Str8BuilderAppendRef(&string_builder, slice); } - DN_Str8 range = DN_Str8_Slice(string, head, (tail - head)); - DN_Str8Builder_AppendRef(&string_builder, range); - DN_Str8Builder_AppendRef(&string_builder, replace); + DN_Str8 range = DN_Str8Slice(string, head, (tail - head)); + DN_Str8BuilderAppendRef(&string_builder, range); + DN_Str8BuilderAppendRef(&string_builder, replace); head = tail + find.size; tail += find.size - 1; // NOTE: -1 since the for loop will post increment us past the end of the find string } if (string_builder.string_size == 0) { // NOTE: No replacement possible, so we just do a full-copy - result = DN_Str8_FromStr8(arena, string); + result = DN_Str8FromStr8Arena(arena, string); } else { - DN_Str8 remainder = DN_Str8_Init(string.data + head, string.size - head); - DN_Str8Builder_AppendRef(&string_builder, remainder); - result = DN_Str8Builder_Build(&string_builder, arena); + DN_Str8 remainder = DN_Str8FromPtr(string.data + head, string.size - head); + DN_Str8BuilderAppendRef(&string_builder, remainder); + result = DN_Str8BuilderBuild(&string_builder, arena); } return result; } -DN_API DN_Str8 DN_Str8_ReplaceInsensitive(DN_Str8 string, DN_Str8 find, DN_Str8 replace, DN_USize start_index, DN_Arena *arena) +DN_API DN_Str8 DN_Str8ReplaceInsensitive(DN_Str8 string, DN_Str8 find, DN_Str8 replace, DN_USize start_index, DN_Arena *arena) { - DN_Str8 result = DN_Str8_Replace(string, find, replace, start_index, arena, DN_Str8EqCase_Insensitive); + DN_Str8 result = DN_Str8Replace(string, find, replace, start_index, arena, DN_Str8EqCase_Insensitive); return result; } // NOTE: DN_Str8Builder //////////////////////////////////////////////////////////////////////////// -DN_API DN_Str8 DN_Str8Builder_BuildFromOSHeap(DN_Str8Builder const *builder) +DN_API DN_Str8 DN_Str8BuilderBuildFromOSHeap(DN_Str8Builder const *builder) { DN_Str8 result = DN_ZeroInit; if (!builder || builder->string_size <= 0 || builder->count <= 0) return result; - result.data = DN_CAST(char *) DN_OS_MemAlloc(builder->string_size + 1, DN_ZeroMem_No); + result.data = DN_Cast(char *) DN_OS_MemAlloc(builder->string_size + 1, DN_ZMem_No); if (!result.data) return result; @@ -6500,10 +6488,10 @@ DN_API int DN_OS_MemProtect(void *ptr, DN_USize size, DN_U32 page_flags) if (!ptr || size == 0) return 0; - static DN_Str8 const ALIGNMENT_ERROR_MSG = DN_STR8( + static DN_Str8 const ALIGNMENT_ERROR_MSG = DN_Str8Lit( "Page protection requires pointers to be page aligned because we " "can only guard memory at a multiple of the page boundary."); - DN_AssertF(DN_IsPowerOfTwoAligned(DN_CAST(uintptr_t) ptr, g_dn_os_core_->page_size), + DN_AssertF(DN_IsPowerOfTwoAligned(DN_Cast(uintptr_t) ptr, g_dn_os_core_->page_size), "%s", ALIGNMENT_ERROR_MSG.data); DN_AssertF( @@ -6515,9 +6503,9 @@ DN_API int DN_OS_MemProtect(void *ptr, DN_USize size, DN_U32 page_flags) return result; } -DN_API void *DN_OS_MemAlloc(DN_USize size, DN_ZeroMem zero_mem) +DN_API void *DN_OS_MemAlloc(DN_USize size, DN_ZMem z_mem) { - void *result = zero_mem == DN_ZeroMem_Yes ? calloc(1, size) : malloc(size); + void *result = z_mem == DN_ZMem_Yes ? calloc(1, size) : malloc(size); return result; } @@ -6548,9 +6536,9 @@ DN_API DN_OSDateTime DN_OS_DateLocalTimeNow() result.minutes = time.tm_min; result.seconds = time.tm_sec; - result.day = DN_CAST(uint8_t) time.tm_mday; - result.month = DN_CAST(uint8_t) time.tm_mon + 1; - result.year = 1900 + DN_CAST(int16_t) time.tm_year; + result.day = DN_Cast(uint8_t) time.tm_mday; + result.month = DN_Cast(uint8_t) time.tm_mon + 1; + result.year = 1900 + DN_Cast(int16_t) time.tm_year; return result; } @@ -6585,7 +6573,7 @@ DN_API uint64_t DN_OS_DateToUnixTimeS(DN_OSDateTime date) DN_API DN_OSDateTime DN_OS_DateUnixTimeSToDate(uint64_t time) { - time_t posix_time = DN_CAST(time_t) time; + time_t posix_time = DN_Cast(time_t) time; struct tm posix_date = *gmtime(&posix_time); DN_OSDateTime result = {}; result.year = posix_date.tm_year + 1900; @@ -6631,7 +6619,7 @@ DN_API DN_OSDiskSpace DN_OS_DiskSpace(DN_Str8 path) { DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr); DN_OSDiskSpace result = {}; - DN_Str8 path_z_terminated = DN_Str8_FromStr8(tmem.arena, path); + DN_Str8 path_z_terminated = DN_Str8FromStr8Arena(tmem.arena, path); struct statvfs info = {}; if (statvfs(path_z_terminated.data, &info) != 0) @@ -6652,7 +6640,7 @@ DN_API DN_Str8 DN_OS_EXEPath(DN_Arena *arena) int required_size_wo_null_terminator = 0; for (int try_size = 128;; try_size *= 2) { auto scoped_arena = DN_ArenaTempMemScope(arena); - char *try_buf = DN_Arena_NewArray(arena, char, try_size, DN_ZeroMem_No); + char *try_buf = DN_ArenaNewArray(arena, char, try_size, DN_ZMem_No); int bytes_written = readlink("/proc/self/exe", try_buf, try_size); if (bytes_written == -1) { // Failed, we're unable to determine the executable directory @@ -6680,9 +6668,9 @@ DN_API DN_Str8 DN_OS_EXEPath(DN_Arena *arena) } if (required_size_wo_null_terminator) { - DN_ArenaTempMem temp_mem = DN_Arena_TempMemBegin(arena); + DN_ArenaTempMem temp_mem = DN_ArenaTempMemBegin(arena); char *exe_path = - DN_Arena_NewArray(arena, char, required_size_wo_null_terminator + 1, DN_ZeroMem_No); + DN_ArenaNewArray(arena, char, required_size_wo_null_terminator + 1, DN_ZMem_No); exe_path[required_size_wo_null_terminator] = 0; int bytes_written = readlink("/proc/self/exe", exe_path, required_size_wo_null_terminator); @@ -6690,9 +6678,9 @@ DN_API DN_Str8 DN_OS_EXEPath(DN_Arena *arena) // Note that if read-link fails again can be because there's // a potential race condition here, our exe or directory could have // been deleted since the last call, so we need to be careful. - DN_Arena_TempMemEnd(temp_mem); + DN_ArenaTempMemEnd(temp_mem); } else { - result = DN_Str8_Init(exe_path, required_size_wo_null_terminator); + result = DN_Str8FromPtr(exe_path, required_size_wo_null_terminator); } } return result; @@ -6719,7 +6707,7 @@ DN_API DN_U64 DN_OS_PerfCounterFrequency() static DN_POSIXCore *DN_OS_GetPOSIXCore_() { DN_Assert(g_dn_os_core_ && g_dn_os_core_->platform_context); - DN_POSIXCore *result = DN_CAST(DN_POSIXCore *)g_dn_os_core_->platform_context; + DN_POSIXCore *result = DN_Cast(DN_POSIXCore *)g_dn_os_core_->platform_context; return result; } @@ -6728,7 +6716,7 @@ DN_API DN_U64 DN_OS_PerfCounterNow() DN_POSIXCore *posix = DN_OS_GetPOSIXCore_(); struct timespec ts; clock_gettime(posix->clock_monotonic_raw ? CLOCK_MONOTONIC_RAW : CLOCK_MONOTONIC, &ts); - DN_U64 result = DN_CAST(DN_U64) ts.tv_sec * 1'000'000'000 + DN_CAST(DN_U64) ts.tv_nsec; + DN_U64 result = DN_Cast(DN_U64) ts.tv_sec * 1'000'000'000 + DN_Cast(DN_U64) ts.tv_nsec; return result; } @@ -6744,7 +6732,7 @@ DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi DN_OS_ErrSinkAppendF(error, error_code, "Failed to open file '%.*s' for copying: (%d) %s", - DN_STR_FMT(src), + DN_Str8PrintFmt(src), error_code, strerror(error_code)); return result; @@ -6761,7 +6749,7 @@ DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi DN_OS_ErrSinkAppendF(error, error_code, "Failed to open file destination '%.*s' for copying to: (%d) %s", - DN_STR_FMT(src), + DN_Str8PrintFmt(src), error_code, strerror(error_code)); return result; @@ -6778,7 +6766,7 @@ DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi DN_OS_ErrSinkAppendF(error, error_code, "Failed to query file size of '%.*s' for copying: (%d) %s", - DN_STR_FMT(src), + DN_Str8PrintFmt(src), error_code, strerror(error_code)); return result; @@ -6789,16 +6777,16 @@ DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi if (!result) { int error_code = errno; DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 file_size_str8 = DN_CVT_BytesStr8FromU64(tmem.arena, stat_existing.st_size, DN_CVTBytesType_Auto); - DN_Str8 bytes_written_str8 = DN_CVT_BytesStr8FromU64(tmem.arena, bytes_written, DN_CVTBytesType_Auto); + DN_Str8 file_size_str8 = DN_Str8FromByteCount(tmem.arena, stat_existing.st_size, DN_ByteCountType_Auto); + DN_Str8 bytes_written_str8 = DN_Str8FromByteCount(tmem.arena, bytes_written, DN_ByteCountType_Auto); DN_OS_ErrSinkAppendF(error, error_code, "Failed to copy file '%.*s' to '%.*s', we copied %.*s but the file " "size is %.*s: (%d) %s", - DN_STR_FMT(src), - DN_STR_FMT(dest), - DN_STR_FMT(bytes_written_str8), - DN_STR_FMT(file_size_str8), + DN_Str8PrintFmt(src), + DN_Str8PrintFmt(dest), + DN_Str8PrintFmt(bytes_written_str8), + DN_Str8PrintFmt(file_size_str8), error_code, strerror(error_code)); } @@ -6827,7 +6815,7 @@ DN_API bool DN_OS_FileMove(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi error, error_code, "File '%.*s' was moved but failed to be unlinked from old location: (%d) %s", - DN_STR_FMT(src), + DN_Str8PrintFmt(src), error_code, strerror(error_code)); } @@ -6841,7 +6829,7 @@ DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path, DN_OSErrSink *error) { DN_OSFile result = {}; - if (!DN_Str8_HasData(path) || path.size <= 0) + if (path.size == 0 || path.size <= 0) return result; if ((access & ~(DN_OSFileAccess_All) || ((access & DN_OSFileAccess_All) == 0))) { @@ -6855,7 +6843,7 @@ DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path, error, 1, "Failed to open file '%.*s': File access flag 'execute' is not supported", - DN_STR_FMT(path)); + DN_Str8PrintFmt(path)); DN_InvalidCodePath; // TODO: Not supported via fopen return result; } @@ -6879,7 +6867,7 @@ DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path, 1, "Failed to open file '%.*s': File could not be opened in requested " "mode 'DN_OSFileOpen' flag %d", - DN_STR_FMT(path), + DN_Str8PrintFmt(path), open_mode); return result; } @@ -6915,10 +6903,10 @@ DN_API DN_OSFileRead DN_OS_FileRead(DN_OSFile *file, void *buffer, DN_USize size if (!file || !file->handle || file->error || !buffer || size <= 0) return result; - result.bytes_read = fread(buffer, 1, size, DN_CAST(FILE *) file->handle); - if (feof(DN_CAST(FILE*)file->handle)) { + result.bytes_read = fread(buffer, 1, size, DN_Cast(FILE *) file->handle); + if (feof(DN_Cast(FILE*)file->handle)) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 buffer_size_str8 = DN_CVT_BytesStr8FromU64AutoTLS(size); + DN_Str8 buffer_size_str8 = DN_ByteCountStr8x32TLS(size); DN_OS_ErrSinkAppendF(err, 1, "Failed to read %S from file", buffer_size_str8); return result; } @@ -6932,12 +6920,12 @@ DN_API bool DN_OS_FileWritePtr(DN_OSFile *file, void const *buffer, DN_USize siz if (!file || !file->handle || file->error || !buffer || size <= 0) return false; bool result = - fwrite(buffer, DN_CAST(DN_USize) size, 1 /*count*/, DN_CAST(FILE *) file->handle) == + fwrite(buffer, DN_Cast(DN_USize) size, 1 /*count*/, DN_Cast(FILE *) file->handle) == 1 /*count*/; if (!result) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 buffer_size_str8 = DN_CVT_BytesStr8FromU64AutoTLS(size); - DN_OS_ErrSinkAppendF(err, 1, "Failed to write buffer (%s) to file handle", DN_STR_FMT(buffer_size_str8)); + DN_Str8 buffer_size_str8 = DN_ByteCountStr8x32TLS(size); + DN_OS_ErrSinkAppendF(err, 1, "Failed to write buffer (%s) to file handle", DN_Str8PrintFmt(buffer_size_str8)); } return result; } @@ -6945,7 +6933,7 @@ DN_API bool DN_OS_FileWritePtr(DN_OSFile *file, void const *buffer, DN_USize siz DN_API bool DN_OS_FileFlush(DN_OSFile *file, DN_OSErrSink *err) { // TODO: errno is not thread safe - int fd = fileno(DN_CAST(FILE *) file->handle); + int fd = fileno(DN_Cast(FILE *) file->handle); if (fd == -1) { DN_OS_ErrSinkAppendF(err, errno, "Failed to flush file buffer to disk, file handle could not be converted to descriptor (%d): %s", fd, strerror(errno)); return false; @@ -6963,14 +6951,14 @@ DN_API void DN_OS_FileClose(DN_OSFile *file) { if (!file || !file->handle || file->error) return; - fclose(DN_CAST(FILE *) file->handle); + fclose(DN_Cast(FILE *) file->handle); *file = {}; } DN_API DN_OSPathInfo DN_OS_PathInfo(DN_Str8 path) { DN_OSPathInfo result = {}; - if (!DN_Str8_HasData(path)) + if (path.size == 0) return result; struct stat file_stat; @@ -6994,7 +6982,7 @@ DN_API DN_OSPathInfo DN_OS_PathInfo(DN_Str8 path) DN_API bool DN_OS_PathDelete(DN_Str8 path) { bool result = false; - if (DN_Str8_HasData(path)) + if (path.size) result = remove(path.data) == 0; return result; } @@ -7002,7 +6990,7 @@ DN_API bool DN_OS_PathDelete(DN_Str8 path) DN_API bool DN_OS_PathIsFile(DN_Str8 path) { bool result = false; - if (!DN_Str8_HasData(path)) + if (path.size == 0) return result; struct stat stat_result; @@ -7014,7 +7002,7 @@ DN_API bool DN_OS_PathIsFile(DN_Str8 path) DN_API bool DN_OS_PathIsDir(DN_Str8 path) { bool result = false; - if (!DN_Str8_HasData(path)) + if (path.size == 0) return result; struct stat stat_result; @@ -7033,7 +7021,7 @@ DN_API bool DN_OS_PathMakeDir(DN_Str8 path) DN_USize path_indexes_size = 0; uint16_t path_indexes[64] = {}; - DN_Str8 copy = DN_Str8_FromStr8(tmem.arena, path); + DN_Str8 copy = DN_Str8FromStr8Arena(tmem.arena, path); for (DN_USize index = copy.size - 1; index < copy.size; index--) { bool first_char = index == (copy.size - 1); char ch = copy.data[index]; @@ -7061,7 +7049,7 @@ DN_API bool DN_OS_PathMakeDir(DN_Str8 path) } else { // NOTE: There's nothing that exists at this path, we can // create a directory here - path_indexes[path_indexes_size++] = DN_CAST(uint16_t) index; + path_indexes[path_indexes_size++] = DN_Cast(uint16_t) index; } } } @@ -7089,23 +7077,23 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it) struct dirent *entry; for (;;) { - entry = readdir(DN_CAST(DIR *) it->handle); + entry = readdir(DN_Cast(DIR *) it->handle); if (entry == NULL) break; if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; - DN_USize name_size = DN_CStr8_Size(entry->d_name); + DN_USize name_size = DN_CStrSize(entry->d_name); DN_USize clamped_size = DN_Min(sizeof(it->buffer) - 1, name_size); DN_AssertF(name_size == clamped_size, "name: %s, name_size: %zu, clamped_size: %zu", entry->d_name, name_size, clamped_size); DN_Memcpy(it->buffer, entry->d_name, clamped_size); it->buffer[clamped_size] = 0; - it->file_name = DN_Str8_Init(it->buffer, clamped_size); + it->file_name = DN_Str8FromPtr(it->buffer, clamped_size); return true; } - closedir(DN_CAST(DIR *) it->handle); + closedir(DN_Cast(DIR *) it->handle); it->handle = NULL; it->file_name = {}; it->buffer[0] = 0; @@ -7114,7 +7102,7 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it) DN_API void DN_OS_Exit(int32_t exit_code) { - exit(DN_CAST(int) exit_code); + exit(DN_Cast(int) exit_code); } enum DN_OSPipeType_ @@ -7192,30 +7180,30 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle, DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena); if (arena && handle.stdout_read) { char buffer[4096]; - DN_Str8Builder builder = DN_Str8Builder_FromArena(tmem.arena); + DN_Str8Builder builder = DN_Str8BuilderFromArena(tmem.arena); for (;;) { ssize_t bytes_read = read(stdout_pipe[DN_OSPipeType__Read], buffer, sizeof(buffer)); if (bytes_read <= 0) break; - DN_Str8Builder_AppendF(&builder, "%.*s", bytes_read, buffer); + DN_Str8BuilderAppendF(&builder, "%.*s", bytes_read, buffer); } - result.stdout_text = DN_Str8Builder_Build(&builder, arena); + result.stdout_text = DN_Str8BuilderBuild(&builder, arena); } if (arena && handle.stderr_read) { char buffer[4096]; - DN_Str8Builder builder = DN_Str8Builder_FromArena(tmem.arena); + DN_Str8Builder builder = DN_Str8BuilderFromArena(tmem.arena); for (;;) { ssize_t bytes_read = read(stderr_pipe[DN_OSPipeType__Read], buffer, sizeof(buffer)); if (bytes_read <= 0) break; - DN_Str8Builder_AppendF(&builder, "%.*s", bytes_read, buffer); + DN_Str8BuilderAppendF(&builder, "%.*s", bytes_read, buffer); } - result.stderr_text = DN_Str8Builder_Build(&builder, arena); + result.stderr_text = DN_Str8BuilderBuild(&builder, arena); } } @@ -7238,7 +7226,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, return result; DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 cmd_rendered = DN_Slice_Str8Render(tmem.arena, cmd_line, DN_STR8(" ")); + DN_Str8 cmd_rendered = DN_Slice_Str8Render(tmem.arena, cmd_line, DN_Str8Lit(" ")); int stdout_pipe[DN_OSPipeType__Count] = {}; int stderr_pipe[DN_OSPipeType__Count] = {}; @@ -7250,7 +7238,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, error, result.os_error_code, "Failed to create stdout pipe to redirect the output of the command '%.*s': %s", - DN_STR_FMT(cmd_rendered), + DN_Str8PrintFmt(cmd_rendered), strerror(result.os_error_code)); return result; } @@ -7277,7 +7265,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, error, result.os_error_code, "Failed to create stderr pipe to redirect the output of the command '%.*s': %s", - DN_STR_FMT(cmd_rendered), + DN_Str8PrintFmt(cmd_rendered), strerror(result.os_error_code)); return result; } @@ -7300,7 +7288,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, error, result.os_error_code, "Failed to fork process to execute the command '%.*s': %s", - DN_STR_FMT(cmd_rendered), + DN_Str8PrintFmt(cmd_rendered), strerror(result.os_error_code)); return result; } @@ -7313,7 +7301,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, error, result.os_error_code, "Failed to redirect stdout 'write' pipe for output of command '%.*s': %s", - DN_STR_FMT(cmd_rendered), + DN_Str8PrintFmt(cmd_rendered), strerror(result.os_error_code)); return result; } @@ -7325,27 +7313,27 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, error, result.os_error_code, "Failed to redirect stderr 'read' pipe for output of command '%.*s': %s", - DN_STR_FMT(cmd_rendered), + DN_Str8PrintFmt(cmd_rendered), strerror(result.os_error_code)); return result; } // NOTE: Convert the command into something suitable for execvp char **argv = - DN_Arena_NewArray(tmem.arena, char *, cmd_line.size + 1 /*null*/, DN_ZeroMem_Yes); + DN_ArenaNewArray(tmem.arena, char *, cmd_line.size + 1 /*null*/, DN_ZMem_Yes); if (!argv) { result.exit_code = -1; DN_OS_ErrSinkAppendF( error, result.os_error_code, "Failed to create argument values from command line '%.*s': Out of memory", - DN_STR_FMT(cmd_rendered)); + DN_Str8PrintFmt(cmd_rendered)); return result; } for (DN_ForIndexU(arg_index, cmd_line.size)) { DN_Str8 arg = cmd_line.data[arg_index]; - argv[arg_index] = DN_Str8_FromStr8(tmem.arena, arg).data; // NOTE: Copy string to guarantee it is null-terminated + argv[arg_index] = DN_Str8FromStr8Arena(tmem.arena, arg).data; // NOTE: Copy string to guarantee it is null-terminated } // NOTE: Change the working directory if there is one @@ -7363,14 +7351,14 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, if (args->working_dir.size) { prev_working_dir = get_current_dir_name(); - DN_Str8 working_dir = DN_Str8_FromStr8(tmem.arena, args->working_dir); + DN_Str8 working_dir = DN_Str8FromStr8Arena(tmem.arena, args->working_dir); if (chdir(working_dir.data) == -1) { result.os_error_code = errno; DN_OS_ErrSinkAppendF( error, result.os_error_code, "Failed to create argument values from command line '%.*s': %s", - DN_STR_FMT(cmd_rendered), + DN_Str8PrintFmt(cmd_rendered), strerror(result.os_error_code)); return result; } @@ -7384,7 +7372,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, error, result.os_error_code, "Failed to execute command'%.*s': %s", - DN_STR_FMT(cmd_rendered), + DN_Str8PrintFmt(cmd_rendered), strerror(result.os_error_code)); return result; } @@ -7451,7 +7439,7 @@ static DN_POSIXSyncPrimitive *DN_POSIX_AllocSyncPrimitive_() result->next = nullptr; } else { DN_OSCore *os = g_dn_os_core_; - result = DN_Arena_New(&os->arena, DN_POSIXSyncPrimitive, DN_ZeroMem_Yes); + result = DN_ArenaNew(&os->arena, DN_POSIXSyncPrimitive, DN_ZMem_Yes); } } pthread_mutex_unlock(&posix->sync_primitive_free_list_mutex); @@ -7707,7 +7695,7 @@ DN_API DN_U32 DN_OS_ThreadID() { pid_t result = gettid(); DN_Assert(gettid() >= 0); - return DN_CAST(DN_U32) result; + return DN_Cast(DN_U32) result; } DN_API void DN_Posix_Init(DN_POSIXCore *posix) @@ -7729,7 +7717,7 @@ DN_API void DN_Posix_ThreadSetName(DN_Str8 name) (void)name; #else DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr); - DN_Str8 copy = DN_Str8_FromStr8(tmem.arena, name); + DN_Str8 copy = DN_Str8FromStr8Arena(tmem.arena, name); pthread_t thread = pthread_self(); pthread_setname_np(thread, (char *)copy.data); #endif @@ -7748,50 +7736,50 @@ DN_API DN_POSIXProcSelfStatus DN_Posix_ProcSelfStatus() // ... // // VmSize is the total virtual memory used - DN_OSFile file = DN_OS_FileOpen(DN_STR8("/proc/self/status"), DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_Read, nullptr); + DN_OSFile file = DN_OS_FileOpen(DN_Str8Lit("/proc/self/status"), DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_Read, nullptr); DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr); if (!file.error) { char buf[256]; - DN_Str8Builder builder = DN_Str8Builder_FromTLS(); + DN_Str8Builder builder = DN_Str8BuilderFromTLS(); for (;;) { DN_OSFileRead read = DN_OS_FileRead(&file, buf, sizeof(buf), nullptr); if (!read.success || read.bytes_read == 0) break; - DN_Str8Builder_AppendF(&builder, "%.*s", DN_CAST(int)read.bytes_read, buf); + DN_Str8BuilderAppendF(&builder, "%.*s", DN_Cast(int)read.bytes_read, buf); } - DN_Str8 const NAME = DN_STR8("Name:"); - DN_Str8 const PID = DN_STR8("Pid:"); - DN_Str8 const VM_PEAK = DN_STR8("VmPeak:"); - DN_Str8 const VM_SIZE = DN_STR8("VmSize:"); - DN_Str8 status_buf = DN_Str8Builder_BuildFromTLS(&builder); - DN_Slice lines = DN_Str8_SplitFromTLS(status_buf, DN_STR8("\n"), DN_Str8SplitIncludeEmptyStrings_No); + DN_Str8 const NAME = DN_Str8Lit("Name:"); + DN_Str8 const PID = DN_Str8Lit("Pid:"); + DN_Str8 const VM_PEAK = DN_Str8Lit("VmPeak:"); + DN_Str8 const VM_SIZE = DN_Str8Lit("VmSize:"); + DN_Str8 status_buf = DN_Str8BuilderBuildFromTLS(&builder); + DN_Slice lines = DN_Str8SplitFromTLS(status_buf, DN_Str8Lit("\n"), DN_Str8SplitIncludeEmptyStrings_No); for (DN_ForIt(line_it, DN_Str8, &lines)) { - DN_Str8 line = DN_Str8_TrimWhitespaceAround(*line_it.data); - if (DN_Str8_StartsWith(line, NAME, DN_Str8EqCase_Insensitive)) { - DN_Str8 str8 = DN_Str8_TrimWhitespaceAround(DN_Str8_Slice(line, NAME.size, line.size)); + DN_Str8 line = DN_Str8TrimWhitespaceAround(*line_it.data); + if (DN_Str8StartsWith(line, NAME, DN_Str8EqCase_Insensitive)) { + DN_Str8 str8 = DN_Str8TrimWhitespaceAround(DN_Str8Slice(line, NAME.size, line.size)); result.name_size = DN_Min(str8.size, sizeof(result.name)); DN_Memcpy(result.name, str8.data, result.name_size); - } else if (DN_Str8_StartsWith(line, PID, DN_Str8EqCase_Insensitive)) { - DN_Str8 str8 = DN_Str8_TrimWhitespaceAround(DN_Str8_Slice(line, PID.size, line.size)); - DN_Str8ToU64Result to_u64 = DN_Str8_ToU64(str8, 0); - result.pid = to_u64.value; + } else if (DN_Str8StartsWith(line, PID, DN_Str8EqCase_Insensitive)) { + DN_Str8 str8 = DN_Str8TrimWhitespaceAround(DN_Str8Slice(line, PID.size, line.size)); + DN_U64FromResult to_u64 = DN_U64FromStr8(str8, 0); + result.pid = to_u64.value; DN_Assert(to_u64.success); - } else if (DN_Str8_StartsWith(line, VM_SIZE, DN_Str8EqCase_Insensitive)) { - DN_Str8 size_with_kb = DN_Str8_TrimWhitespaceAround(DN_Str8_Slice(line, VM_SIZE.size, line.size)); - DN_Assert(DN_Str8_EndsWith(size_with_kb, DN_STR8("kB"))); - DN_Str8 vm_size = DN_Str8_BSplit(size_with_kb, DN_STR8(" ")).lhs; - DN_Str8ToU64Result to_u64 = DN_Str8_ToU64(vm_size, 0); - result.vm_size = DN_Kilobytes(to_u64.value); + } else if (DN_Str8StartsWith(line, VM_SIZE, DN_Str8EqCase_Insensitive)) { + DN_Str8 size_with_kb = DN_Str8TrimWhitespaceAround(DN_Str8Slice(line, VM_SIZE.size, line.size)); + DN_Assert(DN_Str8EndsWith(size_with_kb, DN_Str8Lit("kB"))); + DN_Str8 vm_size = DN_Str8BSplit(size_with_kb, DN_Str8Lit(" ")).lhs; + DN_U64FromResult to_u64 = DN_U64FromStr8(vm_size, 0); + result.vm_size = DN_Kilobytes(to_u64.value); DN_Assert(to_u64.success); - } else if (DN_Str8_StartsWith(line, VM_PEAK, DN_Str8EqCase_Insensitive)) { - DN_Str8 size_with_kb = DN_Str8_TrimWhitespaceAround(DN_Str8_Slice(line, VM_PEAK.size, line.size)); - DN_Assert(DN_Str8_EndsWith(size_with_kb, DN_STR8("kB"))); - DN_Str8 vm_size = DN_Str8_BSplit(size_with_kb, DN_STR8(" ")).lhs; - DN_Str8ToU64Result to_u64 = DN_Str8_ToU64(vm_size, 0); - result.vm_peak = DN_Kilobytes(to_u64.value); + } else if (DN_Str8StartsWith(line, VM_PEAK, DN_Str8EqCase_Insensitive)) { + DN_Str8 size_with_kb = DN_Str8TrimWhitespaceAround(DN_Str8Slice(line, VM_PEAK.size, line.size)); + DN_Assert(DN_Str8EndsWith(size_with_kb, DN_Str8Lit("kB"))); + DN_Str8 vm_size = DN_Str8BSplit(size_with_kb, DN_Str8Lit(" ")).lhs; + DN_U64FromResult to_u64 = DN_U64FromStr8(vm_size, 0); + result.vm_peak = DN_Kilobytes(to_u64.value); DN_Assert(to_u64.success); } } @@ -7846,12 +7834,12 @@ static EM_BOOL EMWebSocketOnCloseCallback(int type, const EmscriptenWebSocketClo #if defined(DN_PLATFORM_EMSCRIPTEN) static void DN_OS_HttpRequestEMFetchOnSuccessCallback(emscripten_fetch_t *fetch) { - DN_OSHttpResponse *response = DN_CAST(DN_OSHttpResponse *) fetch->userData; + DN_OSHttpResponse *response = DN_Cast(DN_OSHttpResponse *) fetch->userData; if (!DN_Check(response)) return; - response->http_status = DN_CAST(DN_U32) fetch->status; - response->body = DN_Str8_Alloc(response->arena, fetch->numBytes, DN_ZeroMem_No); + response->http_status = DN_Cast(DN_U32) fetch->status; + response->body = DN_Str8FromArena(response->arena, fetch->numBytes, DN_ZMem_No); if (response->body.data) DN_Memcpy(response->body.data, fetch->data, fetch->numBytes); @@ -7861,12 +7849,12 @@ static void DN_OS_HttpRequestEMFetchOnSuccessCallback(emscripten_fetch_t *fetch) static void DN_OS_HttpRequestEMFetchOnErrorCallback(emscripten_fetch_t *fetch) { - DN_OSHttpResponse *response = DN_CAST(DN_OSHttpResponse *) fetch->userData; + DN_OSHttpResponse *response = DN_Cast(DN_OSHttpResponse *) fetch->userData; if (!DN_Check(response)) return; - response->http_status = DN_CAST(DN_U32) fetch->status; - response->body = DN_Str8_Alloc(response->arena, fetch->numBytes, DN_ZeroMem_No); + response->http_status = DN_Cast(DN_U32) fetch->status; + response->body = DN_Str8FromArena(response->arena, fetch->numBytes, DN_ZMem_No); if (response->body.size) DN_Memcpy(response->body.data, fetch->data, fetch->numBytes); @@ -7902,15 +7890,15 @@ DN_API void DN_OS_HttpRequestAsync(DN_OSHttpResponse *response, if (method.size >= sizeof(fetch_attribs.requestMethod)) { response->error_msg = - DN_Str8_FromF(arena, + DN_Str8FromFmtArena(arena, "Request method in EM has a size limit of 31 characters, method was " "'%.*s' which is %zu characters long", - DN_STR_FMT(method), + DN_Str8PrintFmt(method), method.size); DN_CheckF(method.size < sizeof(fetch_attribs.requestMethod), "%.*s", - DN_STR_FMT(response->error_msg)); - response->error_code = DN_CAST(DN_U32) - 1; + DN_Str8PrintFmt(response->error_msg)); + response->error_code = DN_Cast(DN_U32) - 1; DN_AtomicAddU32(&response->done, 1); return; } @@ -7924,11 +7912,11 @@ DN_API void DN_OS_HttpRequestAsync(DN_OSHttpResponse *response, fetch_attribs.onerror = DN_OS_HttpRequestEMFetchOnErrorCallback; fetch_attribs.userData = response; - DN_Str8 url = DN_Str8_FromF(tmem, "%.*s%.*s", DN_STR_FMT(host), DN_STR_FMT(path)); + DN_Str8 url = DN_Str8FromFmtArena(tmem, "%.*s%.*s", DN_Str8PrintFmt(host), DN_Str8PrintFmt(path)); DN_LOG_InfoF("Initiating HTTP '%s' request to '%.*s' with payload '%.*s'", fetch_attribs.requestMethod, - DN_STR_FMT(url), - DN_STR_FMT(body)); + DN_Str8PrintFmt(url), + DN_Str8PrintFmt(body)); response->on_complete_semaphore = DN_OS_SemaphoreInit(0); response->em_handle = emscripten_fetch(&fetch_attribs, url.data); #else // #elif defined(DN_OS_WIN32) @@ -7946,7 +7934,7 @@ DN_API void DN_OS_HttpRequestFree(DN_OSHttpResponse *response) } #endif // #elif defined(DN_OS_WIN32) - DN_Arena_Deinit(&response->tmp_arena); + DN_ArenaDeinit(&response->tmp_arena); DN_OS_SemaphoreDeinit(&response->on_complete_semaphore); *response = {}; } @@ -8048,8 +8036,8 @@ DN_API int DN_OS_MemProtect(void *ptr, DN_USize size, DN_U32 page_flags) return 0; static DN_Str8 const ALIGNMENT_ERROR_MSG = - DN_STR8("Page protection requires pointers to be page aligned because we can only guard memory at a multiple of the page boundary."); - DN_AssertF(DN_IsPowerOfTwoAligned(DN_CAST(uintptr_t) ptr, g_dn_os_core_->page_size), "%s", ALIGNMENT_ERROR_MSG.data); + DN_Str8Lit("Page protection requires pointers to be page aligned because we can only guard memory at a multiple of the page boundary."); + DN_AssertF(DN_IsPowerOfTwoAligned(DN_Cast(uintptr_t) ptr, g_dn_os_core_->page_size), "%s", ALIGNMENT_ERROR_MSG.data); DN_AssertF(DN_IsPowerOfTwoAligned(size, g_dn_os_core_->page_size), "%s", ALIGNMENT_ERROR_MSG.data); unsigned long os_page_flags = DN_OS_MemConvertPageToOSFlags_(page_flags); @@ -8062,11 +8050,11 @@ DN_API int DN_OS_MemProtect(void *ptr, DN_USize size, DN_U32 page_flags) return result; } -DN_API void *DN_OS_MemAlloc(DN_USize size, DN_ZeroMem zero_mem) +DN_API void *DN_OS_MemAlloc(DN_USize size, DN_ZMem z_mem) { - DN_U32 flags = zero_mem == DN_ZeroMem_Yes ? HEAP_ZERO_MEMORY : 0; - DN_Assert(size <= DN_CAST(DWORD)(-1)); - void *result = HeapAlloc(GetProcessHeap(), flags, DN_CAST(DWORD) size); + 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); DN_Assert(g_dn_os_core_); DN_AtomicAddU64(&g_dn_os_core_->mem_allocs_total, 1); DN_AtomicAddU64(&g_dn_os_core_->mem_allocs_frame, 1); @@ -8085,12 +8073,12 @@ DN_API DN_OSDateTime DN_OS_DateLocalTimeNow() GetLocalTime(&sys_time); DN_OSDateTime result = {}; - result.hour = DN_CAST(uint8_t) sys_time.wHour; - result.minutes = DN_CAST(uint8_t) sys_time.wMinute; - result.seconds = DN_CAST(uint8_t) sys_time.wSecond; - result.day = DN_CAST(uint8_t) sys_time.wDay; - result.month = DN_CAST(uint8_t) sys_time.wMonth; - result.year = DN_CAST(int16_t) sys_time.wYear; + result.hour = DN_Cast(uint8_t) sys_time.wHour; + result.minutes = DN_Cast(uint8_t) sys_time.wMinute; + result.seconds = DN_Cast(uint8_t) sys_time.wSecond; + result.day = DN_Cast(uint8_t) sys_time.wDay; + result.month = DN_Cast(uint8_t) sys_time.wMonth; + result.year = DN_Cast(int16_t) sys_time.wYear; return result; } @@ -8168,22 +8156,22 @@ DN_API DN_OSDateTime DN_OS_DateUnixTimeSToDate(DN_U64 time) FileTimeToSystemTime(&file_time, &sys_time); DN_OSDateTime result = {}; - result.year = DN_CAST(uint16_t) sys_time.wYear; - result.month = DN_CAST(uint8_t) sys_time.wMonth; - result.day = DN_CAST(uint8_t) sys_time.wDay; - result.hour = DN_CAST(uint8_t) sys_time.wHour; - result.minutes = DN_CAST(uint8_t) sys_time.wMinute; - result.seconds = DN_CAST(uint8_t) sys_time.wSecond; + result.year = DN_Cast(uint16_t) sys_time.wYear; + result.month = DN_Cast(uint8_t) sys_time.wMonth; + result.day = DN_Cast(uint8_t) sys_time.wDay; + result.hour = DN_Cast(uint8_t) sys_time.wHour; + result.minutes = DN_Cast(uint8_t) sys_time.wMinute; + result.seconds = DN_Cast(uint8_t) sys_time.wSecond; return result; } DN_API void DN_OS_GenBytesSecure(void *buffer, DN_U32 size) { DN_Assert(g_dn_os_core_); - DN_W32Core *w32 = DN_CAST(DN_W32Core *) g_dn_os_core_->platform_context; + DN_W32Core *w32 = DN_Cast(DN_W32Core *) g_dn_os_core_->platform_context; DN_Assert(w32->bcrypt_init_success); - long gen_status = BCryptGenRandom(w32->bcrypt_rng_handle, DN_CAST(unsigned char *) buffer, size, 0 /*flags*/); + long gen_status = BCryptGenRandom(w32->bcrypt_rng_handle, DN_Cast(unsigned char *) buffer, size, 0 /*flags*/); // NOTE: This can only fail if the handle is invalid or one or more parameters are invalid. We // validate our parameters so this shouldn't be the case. DN_Assert(gen_status == 0); @@ -8238,7 +8226,7 @@ DN_API void DN_OS_SleepMs(DN_UInt milliseconds) DN_API DN_U64 DN_OS_PerfCounterFrequency() { DN_Assert(g_dn_os_core_); - DN_W32Core *w32 = DN_CAST(DN_W32Core *) g_dn_os_core_->platform_context; + DN_W32Core *w32 = DN_Cast(DN_W32Core *) g_dn_os_core_->platform_context; DN_Assert(w32->qpc_frequency.QuadPart); DN_U64 result = w32->qpc_frequency.QuadPart; return result; @@ -8276,10 +8264,10 @@ DN_API bool DN_OS_FileCopy(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi DN_OS_ErrSinkAppendF(err, win_error.code, "Failed to copy file '%.*s' to '%.*s': (%u) %.*s", - DN_STR_FMT(src), - DN_STR_FMT(dest), + DN_Str8PrintFmt(src), + DN_Str8PrintFmt(dest), win_error.code, - DN_STR_FMT(win_error.msg)); + DN_Str8PrintFmt(win_error.msg)); } return result; } @@ -8301,10 +8289,10 @@ DN_API bool DN_OS_FileMove(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi DN_OS_ErrSinkAppendF(err, win_error.code, "Failed to move file '%.*s' to '%.*s': (%u) %.*s", - DN_STR_FMT(src), - DN_STR_FMT(dest), + DN_Str8PrintFmt(src), + DN_Str8PrintFmt(dest), win_error.code, - DN_STR_FMT(win_error.msg)); + DN_Str8PrintFmt(win_error.msg)); } return result; } @@ -8312,7 +8300,7 @@ DN_API bool DN_OS_FileMove(DN_Str8 src, DN_Str8 dest, bool overwrite, DN_OSErrSi DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path, DN_OSFileOpen open_mode, DN_U32 access, DN_OSErrSink *err) { DN_OSFile result = {}; - if (!DN_Str8_HasData(path) || path.size <= 0) + if (path.size == 0 || path.size <= 0) return result; if ((access & ~DN_OSFileAccess_All) || ((access & DN_OSFileAccess_All) == 0)) { @@ -8355,7 +8343,7 @@ DN_API DN_OSFile DN_OS_FileOpen(DN_Str8 path, DN_OSFileOpen open_mode, DN_U32 ac if (handle == INVALID_HANDLE_VALUE) { DN_W32Error win_error = DN_W32_LastError(tmem.arena); result.error = true; - DN_OS_ErrSinkAppendF(err, win_error.code, "Failed to open file at '%.*s': '%.*s'", DN_STR_FMT(path), DN_STR_FMT(win_error.msg)); + DN_OS_ErrSinkAppendF(err, win_error.code, "Failed to open file at '%.*s': '%.*s'", DN_Str8PrintFmt(path), DN_Str8PrintFmt(win_error.msg)); return result; } @@ -8371,24 +8359,24 @@ DN_API DN_OSFileRead DN_OS_FileRead(DN_OSFile *file, void *buffer, DN_USize size DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); if (!DN_Check(size <= (unsigned long)-1)) { - DN_Str8 buffer_size_str8 = DN_CVT_BytesStr8FromU64AutoTLS(size); + DN_Str8x32 buffer_size_str8 = DN_ByteCountStr8x32(size); DN_OS_ErrSinkAppendF( err, 1 /*error_code*/, "Current implementation doesn't support reading >4GiB file (requested %.*s), implement Win32 overlapped IO", - DN_STR_FMT(buffer_size_str8)); + DN_Str8PrintFmt(buffer_size_str8)); return result; } unsigned long bytes_read = 0; unsigned long read_result = ReadFile(/*HANDLE hFile*/ file->handle, /*LPVOID lpBuffer*/ buffer, - /*DWORD nNumberOfBytesToRead*/ DN_CAST(unsigned long) size, + /*DWORD nNumberOfBytesToRead*/ DN_Cast(unsigned long) size, /*LPDWORD lpNumberOfByesRead*/ &bytes_read, /*LPOVERLAPPED lpOverlapped*/ nullptr); if (read_result == 0) { DN_W32Error win_error = DN_W32_LastError(tmem.arena); - DN_OS_ErrSinkAppendF(err, win_error.code, "Failed to read data from file: (%u) %.*s", win_error.code, DN_STR_FMT(win_error.msg)); + DN_OS_ErrSinkAppendF(err, win_error.code, "Failed to read data from file: (%u) %.*s", win_error.code, DN_Str8PrintFmt(win_error.msg)); return result; } @@ -8399,9 +8387,9 @@ DN_API DN_OSFileRead DN_OS_FileRead(DN_OSFile *file, void *buffer, DN_USize size win_error.code, "Failed to read the desired number of bytes from file, we read %uB but we expected %uB: (%u) %.*s", bytes_read, - DN_CAST(unsigned long) size, + DN_Cast(unsigned long) size, win_error.code, - DN_STR_FMT(win_error.msg)); + DN_Str8PrintFmt(win_error.msg)); return result; } @@ -8416,9 +8404,9 @@ DN_API bool DN_OS_FileWritePtr(DN_OSFile *file, void const *buffer, DN_USize siz return false; bool result = true; - char const *end = DN_CAST(char *) buffer + size; - for (char const *ptr = DN_CAST(char const *) buffer; result && ptr != end;) { - unsigned long write_size = DN_CAST(unsigned long) DN_Min((unsigned long)-1, end - ptr); + char const *end = DN_Cast(char *) buffer + size; + for (char const *ptr = DN_Cast(char const *) buffer; result && ptr != end;) { + unsigned long write_size = DN_Cast(unsigned long) DN_Min((unsigned long)-1, end - ptr); unsigned long bytes_written = 0; result = WriteFile(file->handle, ptr, write_size, &bytes_written, nullptr /*lpOverlapped*/) != 0; ptr += bytes_written; @@ -8427,8 +8415,8 @@ DN_API bool DN_OS_FileWritePtr(DN_OSFile *file, void const *buffer, DN_USize siz if (!result) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); DN_W32Error win_error = DN_W32_LastError(tmem.arena); - DN_Str8 buffer_size_str8 = DN_CVT_BytesStr8FromU64AutoTLS(size); - DN_OS_ErrSinkAppendF(err, win_error.code, "Failed to write buffer (%.*s) to file handle: %.*s", DN_STR_FMT(buffer_size_str8), DN_STR_FMT(win_error.msg)); + DN_Str8x32 buffer_size_str8 = DN_ByteCountStr8x32(size); + DN_OS_ErrSinkAppendF(err, win_error.code, "Failed to write buffer (%.*s) to file handle: %.*s", DN_Str8PrintFmt(buffer_size_str8), DN_Str8PrintFmt(win_error.msg)); } return result; } @@ -8438,14 +8426,14 @@ DN_API bool DN_OS_FileFlush(DN_OSFile *file, DN_OSErrSink *err) if (!file || !file->handle || file->error) return false; - BOOL result = FlushFileBuffers(DN_CAST(HANDLE) file->handle); + BOOL result = FlushFileBuffers(DN_Cast(HANDLE) file->handle); if (!result) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); DN_W32Error win_error = DN_W32_LastError(tmem.arena); - DN_OS_ErrSinkAppendF(err, win_error.code, "Failed to flush file buffer to disk: %.*s", DN_STR_FMT(win_error.msg)); + DN_OS_ErrSinkAppendF(err, win_error.code, "Failed to flush file buffer to disk: %.*s", DN_Str8PrintFmt(win_error.msg)); } - return DN_CAST(bool) result; + return DN_Cast(bool) result; } DN_API void DN_OS_FileClose(DN_OSFile *file) @@ -8459,7 +8447,7 @@ DN_API void DN_OS_FileClose(DN_OSFile *file) DN_API DN_OSPathInfo DN_OS_PathInfo(DN_Str8 path) { DN_OSPathInfo result = {}; - if (!DN_Str8_HasData(path)) + if (path.size == 0) return result; DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); @@ -8475,7 +8463,7 @@ DN_API DN_OSPathInfo DN_OS_PathInfo(DN_Str8 path) result.last_write_time_in_s = DN_W32_FileTimeToSeconds_(&attrib_data.ftLastWriteTime); LARGE_INTEGER large_int = {}; - large_int.u.HighPart = DN_CAST(int32_t) attrib_data.nFileSizeHigh; + large_int.u.HighPart = DN_Cast(int32_t) attrib_data.nFileSizeHigh; large_int.u.LowPart = attrib_data.nFileSizeLow; result.size = (DN_U64)large_int.QuadPart; @@ -8492,7 +8480,7 @@ DN_API DN_OSPathInfo DN_OS_PathInfo(DN_Str8 path) DN_API bool DN_OS_PathDelete(DN_Str8 path) { bool result = false; - if (!DN_Str8_HasData(path)) + if (path.size == 0) return result; DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); @@ -8508,7 +8496,7 @@ DN_API bool DN_OS_PathDelete(DN_Str8 path) DN_API bool DN_OS_PathIsFile(DN_Str8 path) { bool result = false; - if (!DN_Str8_HasData(path)) + if (path.size == 0) return result; DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); @@ -8525,7 +8513,7 @@ DN_API bool DN_OS_PathIsFile(DN_Str8 path) DN_API bool DN_OS_PathIsDir(DN_Str8 path) { bool result = false; - if (!DN_Str8_HasData(path)) + if (path.size == 0) return result; DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); @@ -8593,7 +8581,7 @@ DN_API bool DN_OS_PathMakeDir(DN_Str8 path) DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it) { - if (!DN_Str8_HasData(path) || !it || path.size <= 0) + if (path.size == 0 || !it || path.size <= 0) return false; DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); @@ -8602,10 +8590,10 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it) if (it->handle) { wide_it.handle = it->handle; } else { - bool needs_asterisks = DN_Str8_EndsWith(path, DN_STR8("\\")) || - DN_Str8_EndsWith(path, DN_STR8("/")); - bool has_glob = DN_Str8_EndsWith(path, DN_STR8("\\*")) || - DN_Str8_EndsWith(path, DN_STR8("/*")); + bool needs_asterisks = DN_Str8EndsWith(path, DN_Str8Lit("\\")) || + DN_Str8EndsWith(path, DN_Str8Lit("/")); + bool has_glob = DN_Str8EndsWith(path, DN_Str8Lit("\\*")) || + DN_Str8EndsWith(path, DN_Str8Lit("/*")); DN_Str8 adjusted_path = path; if (!has_glob) { @@ -8613,9 +8601,9 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it) // add those characters in this branch, so overwrite the null // character, add the glob and re-null terminate the buffer. if (needs_asterisks) - adjusted_path = DN_OS_PathF(tmem.arena, "%.*s*", DN_STR_FMT(path)); + adjusted_path = DN_OS_PathF(tmem.arena, "%.*s*", DN_Str8PrintFmt(path)); else - adjusted_path = DN_OS_PathF(tmem.arena, "%.*s/*", DN_STR_FMT(path)); + adjusted_path = DN_OS_PathF(tmem.arena, "%.*s/*", DN_Str8PrintFmt(path)); } path16 = DN_W32_Str8ToStr16(tmem.arena, adjusted_path); @@ -8627,7 +8615,7 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it) it->handle = wide_it.handle; if (result) { int size = DN_W32_Str16ToStr8Buffer(wide_it.file_name, it->buffer, DN_ArrayCountU(it->buffer)); - it->file_name = DN_Str8_Init(it->buffer, size); + it->file_name = DN_Str8FromPtr(it->buffer, size); } return result; @@ -8637,7 +8625,7 @@ DN_API bool DN_OS_PathIterateDir(DN_Str8 path, DN_OSDirIterator *it) // NOTE: DN_OSExec ///////////////////////////////////////////////////////////////////////////////// DN_API void DN_OS_Exit(int32_t exit_code) { - ExitProcess(DN_CAST(UINT) exit_code); + ExitProcess(DN_Cast(UINT) exit_code); } DN_API DN_OSExecResult DN_OS_ExecPump(DN_OSExecAsyncHandle handle, @@ -8688,7 +8676,7 @@ DN_API DN_OSExecResult DN_OS_ExecPump(DN_OSExecAsyncHandle handle, if (exec_result == WAIT_FAILED) { DN_W32Error win_error = DN_W32_LastError(tmem.arena); result.os_error_code = win_error.code; - DN_OS_ErrSinkAppendF(err, result.os_error_code, "Executed command failed to terminate: %.*s", DN_STR_FMT(win_error.msg)); + DN_OS_ErrSinkAppendF(err, result.os_error_code, "Executed command failed to terminate: %.*s", DN_Str8PrintFmt(win_error.msg)); } else if (DN_Check(exec_result == WAIT_TIMEOUT || exec_result == WAIT_OBJECT_0)) { // NOTE: Read stdout from process ////////////////////////////////////////////////////// // If the pipes are full, the process will block. We periodically @@ -8700,7 +8688,7 @@ DN_API DN_OSExecResult DN_OS_ExecPump(DN_OSExecAsyncHandle handle, DWORD bytes_read = 0; char *dest_buffer = handle.stdout_write && stdout_buffer ? stdout_buffer : sink; size_t dest_size = handle.stdout_write && stdout_buffer ? stdout_buffer_size : DN_ArrayCountU(sink); - BOOL success = ReadFile(handle.stdout_read, dest_buffer, DN_CAST(DWORD) dest_size, &bytes_read, NULL); + BOOL success = ReadFile(handle.stdout_read, dest_buffer, DN_Cast(DWORD) dest_size, &bytes_read, NULL); (void)success; // TODO: if (stdout_size) *stdout_size = bytes_read; @@ -8714,7 +8702,7 @@ DN_API DN_OSExecResult DN_OS_ExecPump(DN_OSExecAsyncHandle handle, char *dest_buffer = handle.stderr_write && stderr_buffer ? stderr_buffer : sink; size_t dest_size = handle.stderr_write && stderr_buffer ? stderr_buffer_size : DN_ArrayCountU(sink); DWORD bytes_read = 0; - BOOL success = ReadFile(handle.stderr_read, dest_buffer, DN_CAST(DWORD) dest_size, &bytes_read, NULL); + BOOL success = ReadFile(handle.stderr_read, dest_buffer, DN_Cast(DWORD) dest_size, &bytes_read, NULL); (void)success; // TODO: if (stderr_size) *stderr_size = bytes_read; @@ -8733,7 +8721,7 @@ DN_API DN_OSExecResult DN_OS_ExecPump(DN_OSExecAsyncHandle handle, DN_OS_ErrSinkAppendF(err, result.os_error_code, "Failed to retrieve command exit code: %.*s", - DN_STR_FMT(win_error.msg)); + DN_Str8PrintFmt(win_error.msg)); } // NOTE: Cleanup /////////////////////////////////////////////////////////////////////////////// @@ -8744,8 +8732,8 @@ DN_API DN_OSExecResult DN_OS_ExecPump(DN_OSExecAsyncHandle handle, CloseHandle(handle.process); } - result.stdout_text = DN_Str8_Init(stdout_buffer, stdout_size ? *stdout_size : 0); - result.stderr_text = DN_Str8_Init(stderr_buffer, stderr_size ? *stderr_size : 0); + result.stdout_text = DN_Str8FromPtr(stdout_buffer, stdout_size ? *stdout_size : 0); + result.stderr_text = DN_Str8FromPtr(stderr_buffer, stderr_size ? *stderr_size : 0); return result; } @@ -8781,17 +8769,17 @@ DN_API DN_OSExecResult DN_OS_ExecWait(DN_OSExecAsyncHandle handle, DN_Arena *are while (!result.finished) { size_t stdout_size = DN_Kilobytes(8); size_t stderr_size = DN_Kilobytes(8); - char *stdout_buffer = DN_Arena_NewArray(tmem.arena, char, stdout_size, DN_ZeroMem_No); - char *stderr_buffer = DN_Arena_NewArray(tmem.arena, char, stderr_size, DN_ZeroMem_No); + char *stdout_buffer = DN_ArenaNewArray(tmem.arena, char, stdout_size, DN_ZMem_No); + char *stderr_buffer = DN_ArenaNewArray(tmem.arena, char, stderr_size, DN_ZMem_No); result = DN_OS_ExecPump(handle, stdout_buffer, &stdout_size, stderr_buffer, &stderr_size, wait_ms, err); - DN_Str8Builder_AppendCopy(&stdout_builder, result.stdout_text); - DN_Str8Builder_AppendCopy(&stderr_builder, result.stderr_text); - wait_ms = (DN_Str8_HasData(result.stdout_text) || DN_Str8_HasData(result.stderr_text)) ? FAST_WAIT_TIME_MS : SLOW_WAIT_TIME_MS; + DN_Str8BuilderAppendCopy(&stdout_builder, result.stdout_text); + DN_Str8BuilderAppendCopy(&stderr_builder, result.stderr_text); + wait_ms = (result.stdout_text.size || result.stderr_text.size) ? FAST_WAIT_TIME_MS : SLOW_WAIT_TIME_MS; } // NOTE: Get stdout/stderr. If no arena is passed this is a no-op ////////////////////////////// - result.stdout_text = DN_Str8Builder_Build(&stdout_builder, arena); - result.stderr_text = DN_Str8Builder_Build(&stderr_builder, arena); + result.stdout_text = DN_Str8BuilderBuild(&stdout_builder, arena); + result.stderr_text = DN_Str8BuilderBuild(&stderr_builder, arena); return result; } @@ -8803,16 +8791,16 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, DN_OSExe return result; DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 cmd_rendered = DN_Slice_Str8Render(tmem.arena, cmd_line, DN_STR8(" ")); + DN_Str8 cmd_rendered = DN_Slice_Str8Render(tmem.arena, cmd_line, DN_Str8Lit(" ")); DN_Str16 cmd16 = DN_W32_Str8ToStr16(tmem.arena, cmd_rendered); DN_Str16 working_dir16 = DN_W32_Str8ToStr16(tmem.arena, args->working_dir); - DN_Str8Builder env_builder = DN_Str8Builder_FromTLS(); - DN_Str8Builder_AppendArrayRef(&env_builder, args->environment.data, args->environment.size); + DN_Str8Builder env_builder = DN_Str8BuilderFromTLS(); + DN_Str8BuilderAppendArrayRef(&env_builder, args->environment.data, args->environment.size); if (env_builder.string_size) - DN_Str8Builder_AppendRef(&env_builder, DN_STR8("\0")); + DN_Str8BuilderAppendRef(&env_builder, DN_Str8Lit("\0")); - DN_Str8 env_block8 = DN_Str8Builder_BuildDelimitedFromTLS(&env_builder, DN_STR8("\0")); + DN_Str8 env_block8 = DN_Str8BuilderBuildDelimitedFromTLS(&env_builder, DN_Str8Lit("\0")); DN_Str16 env_block16 = {}; if (env_block8.size) env_block16 = DN_W32_Str8ToStr16(tmem.arena, env_block8); @@ -8841,8 +8829,8 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, DN_OSExe err, result.os_error_code, "Failed to create stdout pipe to redirect the output of the command '%.*s': %.*s", - DN_STR_FMT(cmd_rendered), - DN_STR_FMT(win_error.msg)); + DN_Str8PrintFmt(cmd_rendered), + DN_Str8PrintFmt(win_error.msg)); return result; } @@ -8853,8 +8841,8 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, DN_OSExe result.os_error_code, "Failed to make stdout 'read' pipe non-inheritable when trying to " "execute command '%.*s': %.*s", - DN_STR_FMT(cmd_rendered), - DN_STR_FMT(win_error.msg)); + DN_Str8PrintFmt(cmd_rendered), + DN_Str8PrintFmt(win_error.msg)); return result; } } @@ -8882,8 +8870,8 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, DN_OSExe err, result.os_error_code, "Failed to create stderr pipe to redirect the output of the command '%.*s': %.*s", - DN_STR_FMT(cmd_rendered), - DN_STR_FMT(win_error.msg)); + DN_Str8PrintFmt(cmd_rendered), + DN_Str8PrintFmt(win_error.msg)); return result; } @@ -8894,8 +8882,8 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, DN_OSExe result.os_error_code, "Failed to make stderr 'read' pipe non-inheritable when trying to " "execute command '%.*s': %.*s", - DN_STR_FMT(cmd_rendered), - DN_STR_FMT(win_error.msg)); + DN_Str8PrintFmt(cmd_rendered), + DN_Str8PrintFmt(win_error.msg)); return result; } } @@ -8925,8 +8913,8 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, DN_OSExe DN_OS_ErrSinkAppendF(err, result.os_error_code, "Failed to execute command '%.*s': %.*s", - DN_STR_FMT(cmd_rendered), - DN_STR_FMT(win_error.msg)); + DN_Str8PrintFmt(cmd_rendered), + DN_Str8PrintFmt(win_error.msg)); return result; } @@ -8946,7 +8934,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, DN_OSExe static DN_W32Core *DN_OS_GetW32Core_() { DN_Assert(g_dn_os_core_ && g_dn_os_core_->platform_context); - DN_W32Core *result = DN_CAST(DN_W32Core *)g_dn_os_core_->platform_context; + DN_W32Core *result = DN_Cast(DN_W32Core *)g_dn_os_core_->platform_context; return result; } @@ -8977,7 +8965,7 @@ static DN_W32SyncPrimitive *DN_W32_AllocSyncPrimitive_() result->next = nullptr; } else { DN_OSCore *os = g_dn_os_core_; - result = DN_Arena_New(&os->arena, DN_W32SyncPrimitive, DN_ZeroMem_Yes); + result = DN_ArenaNew(&os->arena, DN_W32SyncPrimitive, DN_ZMem_Yes); } } LeaveCriticalSection(&w32->sync_primitive_free_list_mutex); @@ -9118,7 +9106,7 @@ DN_API bool DN_OS_ConditionVariableWait(DN_OSConditionVariable *cv, DN_OSMutex * if (mutex && cv && mutex->handle != 0 && cv->handle != 0 && sleep_ms > 0) { DN_W32SyncPrimitive *mutex_primitive = DN_OS_U64ToW32SyncPrimitive_(mutex->handle); DN_W32SyncPrimitive *cv_primitive = DN_OS_U64ToW32SyncPrimitive_(cv->handle); - result = SleepConditionVariableCS(&cv_primitive->cv, &mutex_primitive->mutex, DN_CAST(DWORD) sleep_ms); + result = SleepConditionVariableCS(&cv_primitive->cv, &mutex_primitive->mutex, DN_Cast(DWORD) sleep_ms); } return result; } @@ -9202,7 +9190,7 @@ DN_API DN_U32 DN_OS_ThreadID() DN_API void DN_W32_ThreadSetName(DN_Str8 name) { DN_OSTLS *tls = DN_OS_TLSGet(); - DN_ArenaTempMem tmem = DN_Arena_TempMemBegin(tls->arenas + DN_OSTLSArena_TMem0); + DN_ArenaTempMem tmem = DN_ArenaTempMemBegin(tls->arenas + DN_OSTLSArena_TMem0); // NOTE: SetThreadDescription is only available in // Windows Server 2016, Windows 10 LTSB 2016 and Windows 10 version 1607 @@ -9212,7 +9200,7 @@ DN_API void DN_W32_ThreadSetName(DN_Str8 name) if (w32->set_thread_description) { DN_Str16 name16 = DN_W32_Str8ToStr16(tmem.arena, name); w32->set_thread_description(GetCurrentThread(), (WCHAR *)name16.data); - DN_Arena_TempMemEnd(tmem); + DN_ArenaTempMemEnd(tmem); return; } @@ -9229,7 +9217,7 @@ DN_API void DN_W32_ThreadSetName(DN_Str8 name) #pragma pack(pop) - DN_Str8 copy = DN_Str8_FromStr8(tmem.arena, name); + DN_Str8 copy = DN_Str8FromStr8Arena(tmem.arena, name); DN_W32ThreadNameInfo info = {}; info.dwType = 0x1000; info.szName = (char *)copy.data; @@ -9245,7 +9233,7 @@ DN_API void DN_W32_ThreadSetName(DN_Str8 name) } DN_MSVC_WARNING_POP - DN_Arena_TempMemEnd(tmem); + DN_ArenaTempMemEnd(tmem); } // NOTE: DN_OSHttp ///////////////////////////////////////////////////////////////////////////////// @@ -9254,8 +9242,8 @@ void DN_OS_HttpRequestWin32Callback(HINTERNET session, DWORD *dwContext, DWORD d (void)session; (void)dwStatusInformationLength; - DN_OSHttpResponse *response = DN_CAST(DN_OSHttpResponse *) dwContext; - HINTERNET request = DN_CAST(HINTERNET) response->w32_request_handle; + DN_OSHttpResponse *response = DN_Cast(DN_OSHttpResponse *) dwContext; + HINTERNET request = DN_Cast(HINTERNET) response->w32_request_handle; DN_W32Error error = {}; DWORD const READ_BUFFER_SIZE = DN_Megabytes(1); @@ -9285,7 +9273,7 @@ void DN_OS_HttpRequestWin32Callback(HINTERNET session, DWORD *dwContext, DWORD d &status, &status_size, WINHTTP_NO_HEADER_INDEX)) { - response->http_status = DN_CAST(uint16_t) status; + response->http_status = DN_Cast(uint16_t) status; // NOTE: You can normally call into WinHttpQueryDataAvailable which means the kernel // will buffer the response into a single buffer and return us the full size of the @@ -9297,7 +9285,7 @@ void DN_OS_HttpRequestWin32Callback(HINTERNET session, DWORD *dwContext, DWORD d // This is advantageous to avoid a copy from the kernel buffer into our buffer. If the // end user application knows the typical payload size then they can optimise for this // to prevent unnecessary allocation on the user side. - void *buffer = DN_Arena_Alloc(response->builder.arena, READ_BUFFER_SIZE, 1 /*align*/, DN_ZeroMem_No); + void *buffer = DN_ArenaAlloc(response->builder.arena, READ_BUFFER_SIZE, 1 /*align*/, DN_ZMem_No); if (!WinHttpReadData(request, buffer, READ_BUFFER_SIZE, nullptr)) error = DN_W32_LastError(&response->tmp_arena); } else { @@ -9307,17 +9295,17 @@ void DN_OS_HttpRequestWin32Callback(HINTERNET session, DWORD *dwContext, DWORD d } else if (dwInternetStatus == WINHTTP_CALLBACK_STATUS_READ_COMPLETE) { DWORD bytes_read = dwStatusInformationLength; if (bytes_read) { - DN_Str8 prev_buffer = DN_Str8_Init(DN_CAST(char *) lpvStatusInformation, bytes_read); - DN_Str8Builder_AppendRef(&response->builder, prev_buffer); + DN_Str8 prev_buffer = DN_Str8FromPtr(DN_Cast(char *) lpvStatusInformation, bytes_read); + DN_Str8BuilderAppendRef(&response->builder, prev_buffer); - void *buffer = DN_Arena_Alloc(response->builder.arena, READ_BUFFER_SIZE, 1 /*align*/, DN_ZeroMem_No); + void *buffer = DN_ArenaAlloc(response->builder.arena, READ_BUFFER_SIZE, 1 /*align*/, DN_ZMem_No); if (!WinHttpReadData(request, buffer, READ_BUFFER_SIZE, nullptr)) error = DN_W32_LastError(&response->tmp_arena); } } else if (dwInternetStatus == WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE) { } else if (dwInternetStatus == WINHTTP_CALLBACK_STATUS_REQUEST_ERROR) { - WINHTTP_ASYNC_RESULT *async_result = DN_CAST(WINHTTP_ASYNC_RESULT *) lpvStatusInformation; - error = DN_W32_ErrorCodeToMsg(&response->tmp_arena, DN_CAST(DN_U32) async_result->dwError); + WINHTTP_ASYNC_RESULT *async_result = DN_Cast(WINHTTP_ASYNC_RESULT *) lpvStatusInformation; + error = DN_W32_ErrorCodeToMsg(&response->tmp_arena, DN_Cast(DN_U32) async_result->dwError); } else if (dwInternetStatus == WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE) { if (!WinHttpReceiveResponse(request, 0)) error = DN_W32_LastError(&response->tmp_arena); @@ -9329,7 +9317,7 @@ void DN_OS_HttpRequestWin32Callback(HINTERNET session, DWORD *dwContext, DWORD d if (request) { bool read_complete = dwInternetStatus == WINHTTP_CALLBACK_STATUS_READ_COMPLETE && dwStatusInformationLength == 0; if (read_complete) - response->body = DN_Str8Builder_Build(&response->builder, response->arena); + response->body = DN_Str8BuilderBuild(&response->builder, response->arena); if (read_complete || dwInternetStatus == WINHTTP_CALLBACK_STATUS_REQUEST_ERROR || error.code) { DN_OS_SemaphoreIncrement(&response->on_complete_semaphore, 1); @@ -9387,9 +9375,9 @@ DN_API void DN_OS_HttpRequestAsync(DN_OSHttpResponse *response, WINHTTP_CALLBACK_STATUS_REQUEST_ERROR | WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE; if (WinHttpSetStatusCallback(response->w32_request_session, - DN_CAST(WINHTTP_STATUS_CALLBACK) DN_OS_HttpRequestWin32Callback, + DN_Cast(WINHTTP_STATUS_CALLBACK) DN_OS_HttpRequestWin32Callback, callback_flags, - DN_CAST(DWORD_PTR) nullptr /*dwReserved*/) == WINHTTP_INVALID_STATUS_CALLBACK) { + DN_Cast(DWORD_PTR) nullptr /*dwReserved*/) == WINHTTP_INVALID_STATUS_CALLBACK) { error = DN_W32_LastError(&response->tmp_arena); return; } @@ -9419,11 +9407,11 @@ DN_API void DN_OS_HttpRequestAsync(DN_OSHttpResponse *response, response->on_complete_semaphore = DN_OS_SemaphoreInit(0); if (!WinHttpSendRequest(response->w32_request_handle, headers16.data, - DN_CAST(DWORD) headers16.size, + DN_Cast(DWORD) headers16.size, body.data /*optional data*/, - DN_CAST(DWORD) body.size /*optional length*/, - DN_CAST(DWORD) body.size /*total content length*/, - DN_CAST(DWORD_PTR) response)) { + DN_Cast(DWORD) body.size /*optional length*/, + DN_Cast(DWORD) body.size /*total content length*/, + DN_Cast(DWORD_PTR) response)) { error = DN_W32_LastError(&response->tmp_arena); return; } @@ -9440,7 +9428,7 @@ DN_API void DN_OS_HttpRequestFree(DN_OSHttpResponse *response) response->w32_request_session = nullptr; response->w32_request_connection = nullptr; response->w32_request_handle = nullptr; - DN_Arena_Deinit(&response->tmp_arena); + DN_ArenaDeinit(&response->tmp_arena); DN_OS_SemaphoreDeinit(&response->on_complete_semaphore); *response = {}; @@ -9523,11 +9511,11 @@ DN_API void DN_W32_MakeProcessDPIAware() if (!lib_handle) return; - if (auto *set_process_dpi_awareness_context = DN_CAST(SetProcessDpiAwarenessContextProc *) GetProcAddress(DN_CAST(HMODULE) lib_handle, "SetProcessDpiAwarenessContext")) + if (auto *set_process_dpi_awareness_context = DN_Cast(SetProcessDpiAwarenessContextProc *) GetProcAddress(DN_Cast(HMODULE) lib_handle, "SetProcessDpiAwarenessContext")) set_process_dpi_awareness_context(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); - else if (auto *set_process_dpi_awareness = DN_CAST(SetProcessDpiAwarenessProc *) GetProcAddress(DN_CAST(HMODULE) lib_handle, "SetProcessDpiAwareness")) + else if (auto *set_process_dpi_awareness = DN_Cast(SetProcessDpiAwarenessProc *) GetProcAddress(DN_Cast(HMODULE) lib_handle, "SetProcessDpiAwareness")) set_process_dpi_awareness(DPI_AWARENESS_PER_MONITOR_AWARE); - else if (auto *set_process_dpi_aware = DN_CAST(SetProcessDpiAwareProc *) GetProcAddress(DN_CAST(HMODULE) lib_handle, "SetProcessDpiAware")) + else if (auto *set_process_dpi_aware = DN_Cast(SetProcessDpiAwareProc *) GetProcAddress(DN_Cast(HMODULE) lib_handle, "SetProcessDpiAware")) set_process_dpi_aware(); } @@ -9535,18 +9523,18 @@ DN_API void DN_W32_MakeProcessDPIAware() DN_API DN_Str16 DN_W32_Str8ToStr16(DN_Arena *arena, DN_Str8 src) { DN_Str16 result = {}; - if (!arena || !DN_Str8_HasData(src)) + if (!arena || src.size == 0) return result; - int required_size = MultiByteToWideChar(CP_UTF8, 0 /*dwFlags*/, src.data, DN_CAST(int) src.size, nullptr /*dest*/, 0 /*dest size*/); + int required_size = MultiByteToWideChar(CP_UTF8, 0 /*dwFlags*/, src.data, DN_Cast(int) src.size, nullptr /*dest*/, 0 /*dest size*/); if (required_size <= 0) return result; - wchar_t *buffer = DN_Arena_NewArray(arena, wchar_t, required_size + 1, DN_ZeroMem_No); + wchar_t *buffer = DN_ArenaNewArray(arena, wchar_t, required_size + 1, DN_ZMem_No); if (!buffer) return result; - int chars_written = MultiByteToWideChar(CP_UTF8, 0 /*dwFlags*/, src.data, DN_CAST(int) src.size, buffer, required_size); + int chars_written = MultiByteToWideChar(CP_UTF8, 0 /*dwFlags*/, src.data, DN_Cast(int) src.size, buffer, required_size); if (DN_Check(chars_written == required_size)) { result.data = buffer; result.size = chars_written; @@ -9558,14 +9546,14 @@ DN_API DN_Str16 DN_W32_Str8ToStr16(DN_Arena *arena, DN_Str8 src) DN_API int DN_W32_Str8ToStr16Buffer(DN_Str8 src, wchar_t *dest, int dest_size) { int result = 0; - if (!DN_Str8_HasData(src)) + if (src.size == 0) return result; - result = MultiByteToWideChar(CP_UTF8, 0 /*dwFlags*/, src.data, DN_CAST(int) src.size, nullptr /*dest*/, 0 /*dest size*/); + result = MultiByteToWideChar(CP_UTF8, 0 /*dwFlags*/, src.data, DN_Cast(int) src.size, nullptr /*dest*/, 0 /*dest size*/); if (result <= 0 || result > dest_size || !dest) return result; - result = MultiByteToWideChar(CP_UTF8, 0 /*dwFlags*/, src.data, DN_CAST(int) src.size, dest, DN_CAST(int) dest_size); + result = MultiByteToWideChar(CP_UTF8, 0 /*dwFlags*/, src.data, DN_Cast(int) src.size, dest, DN_Cast(int) dest_size); dest[DN_Min(result, dest_size - 1)] = 0; return result; } @@ -9574,7 +9562,7 @@ DN_API int DN_W32_Str8ToStr16Buffer(DN_Str8 src, wchar_t *dest, int dest_size) DN_API int DN_W32_Str16ToStr8Buffer(DN_Str16 src, char *dest, int dest_size) { int result = 0; - if (!DN_Str16_HasData(src)) + if (src.size == 0) return result; int src_size = DN_SaturateCastISizeToInt(src.size); @@ -9585,7 +9573,7 @@ DN_API int DN_W32_Str16ToStr8Buffer(DN_Str16 src, char *dest, int dest_size) if (result <= 0 || result > dest_size || !dest) return result; - result = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, src.data, src_size, dest, DN_CAST(int) dest_size, nullptr, nullptr); + result = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, src.data, src_size, dest, DN_Cast(int) dest_size, nullptr, nullptr); dest[DN_Min(result, dest_size - 1)] = 0; return result; } @@ -9593,7 +9581,7 @@ DN_API int DN_W32_Str16ToStr8Buffer(DN_Str16 src, char *dest, int dest_size) DN_API DN_Str8 DN_W32_Str16ToStr8(DN_Arena *arena, DN_Str16 src) { DN_Str8 result = {}; - if (!arena || !DN_Str16_HasData(src)) + if (!arena || src.size == 0) return result; int src_size = DN_SaturateCastISizeToInt(src.size); @@ -9607,11 +9595,11 @@ DN_API DN_Str8 DN_W32_Str16ToStr8(DN_Arena *arena, DN_Str16 src) // NOTE: Str8 allocate ensures there's one extra byte for // null-termination already so no-need to +1 the required size DN_ArenaTempMemScope temp_mem = DN_ArenaTempMemScope(arena); - DN_Str8 buffer = DN_Str8_Alloc(arena, required_size, DN_ZeroMem_No); - if (!DN_Str8_HasData(buffer)) + DN_Str8 buffer = DN_Str8FromArena(arena, required_size, DN_ZMem_No); + if (buffer.size == 0) return result; - int chars_written = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, src.data, src_size, buffer.data, DN_CAST(int) buffer.size, nullptr, nullptr); + int chars_written = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, src.data, src_size, buffer.data, DN_Cast(int) buffer.size, nullptr, nullptr); if (DN_Check(chars_written == required_size)) { result = buffer; result.data[result.size] = 0; @@ -9624,7 +9612,7 @@ DN_API DN_Str8 DN_W32_Str16ToStr8(DN_Arena *arena, DN_Str16 src) DN_API DN_Str8 DN_W32_Str16ToStr8FromHeap(DN_Str16 src) { DN_Str8 result = {}; - if (!DN_Str16_HasData(src)) + if (src.size == 0) return result; int src_size = DN_SaturateCastISizeToInt(src.size); @@ -9637,11 +9625,11 @@ DN_API DN_Str8 DN_W32_Str16ToStr8FromHeap(DN_Str16 src) // NOTE: Str8 allocate ensures there's one extra byte for // null-termination already so no-need to +1 the required size - DN_Str8 buffer = DN_Str8_FromHeap(required_size, DN_ZeroMem_No); - if (!DN_Str8_HasData(buffer)) + DN_Str8 buffer = DN_Str8FromHeap(required_size, DN_ZMem_No); + if (buffer.size == 0) return result; - int chars_written = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, src.data, src_size, buffer.data, DN_CAST(int) buffer.size, nullptr, nullptr); + int chars_written = WideCharToMultiByte(CP_UTF8, 0 /*dwFlags*/, src.data, src_size, buffer.data, DN_Cast(int) buffer.size, nullptr, nullptr); if (DN_Check(chars_written == required_size)) { result = buffer; result.data[result.size] = 0; @@ -9662,17 +9650,17 @@ DN_API DN_Str16 DN_W32_EXEPathW(DN_Arena *arena) wchar_t *module_path = nullptr; do { module_size += 256; - module_path = DN_Arena_NewArray(tmem.arena, wchar_t, module_size, DN_ZeroMem_No); + module_path = DN_ArenaNewArray(tmem.arena, wchar_t, module_size, DN_ZMem_No); if (!module_path) return result; - module_size = DN_CAST(DN_USize) GetModuleFileNameW(nullptr /*module*/, module_path, DN_CAST(int) module_size); + module_size = DN_Cast(DN_USize) GetModuleFileNameW(nullptr /*module*/, module_path, DN_Cast(int) module_size); } while (GetLastError() == ERROR_INSUFFICIENT_BUFFER); DN_USize index_of_last_slash = 0; for (DN_USize index = module_size - 1; !index_of_last_slash && index < module_size; index--) index_of_last_slash = module_path[index] == '\\' ? index : 0; - result.data = DN_Arena_NewArray(arena, wchar_t, module_size + 1, DN_ZeroMem_No); + result.data = DN_ArenaNewArray(arena, wchar_t, module_size + 1, DN_ZMem_No); result.size = module_size; DN_Memcpy(result.data, module_path, sizeof(wchar_t) * result.size); result.data[result.size] = 0; @@ -9688,17 +9676,17 @@ DN_API DN_Str16 DN_W32_EXEDirW(DN_Arena *arena) wchar_t *module_path = nullptr; do { module_size += 256; - module_path = DN_Arena_NewArray(tmem.arena, wchar_t, module_size, DN_ZeroMem_No); + module_path = DN_ArenaNewArray(tmem.arena, wchar_t, module_size, DN_ZMem_No); if (!module_path) return result; - module_size = DN_CAST(DN_USize) GetModuleFileNameW(nullptr /*module*/, module_path, DN_CAST(int) module_size); + module_size = DN_Cast(DN_USize) GetModuleFileNameW(nullptr /*module*/, module_path, DN_Cast(int) module_size); } while (GetLastError() == ERROR_INSUFFICIENT_BUFFER); DN_USize index_of_last_slash = 0; for (DN_USize index = module_size - 1; !index_of_last_slash && index < module_size; index--) index_of_last_slash = module_path[index] == '\\' ? index : 0; - result.data = DN_Arena_NewArray(arena, wchar_t, index_of_last_slash + 1, DN_ZeroMem_No); + result.data = DN_ArenaNewArray(arena, wchar_t, index_of_last_slash + 1, DN_ZMem_No); result.size = index_of_last_slash; DN_Memcpy(result.data, module_path, sizeof(wchar_t) * result.size); result.data[result.size] = 0; @@ -9722,9 +9710,9 @@ DN_API DN_Str16 DN_W32_WorkingDirW(DN_Arena *arena, DN_Str16 suffix) // NOTE: required_size is the size required *including* the null-terminator DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena); unsigned long required_size = GetCurrentDirectoryW(0, nullptr); - unsigned long desired_size = required_size + DN_CAST(unsigned long) suffix.size; + unsigned long desired_size = required_size + DN_Cast(unsigned long) suffix.size; - wchar_t *tmem_w_path = DN_Arena_NewArray(tmem.arena, wchar_t, desired_size, DN_ZeroMem_No); + wchar_t *tmem_w_path = DN_ArenaNewArray(tmem.arena, wchar_t, desired_size, DN_ZMem_No); if (!tmem_w_path) return result; @@ -9734,7 +9722,7 @@ DN_API DN_Str16 DN_W32_WorkingDirW(DN_Arena *arena, DN_Str16 suffix) return result; } - wchar_t *w_path = DN_Arena_NewArray(arena, wchar_t, desired_size, DN_ZeroMem_No); + wchar_t *w_path = DN_ArenaNewArray(arena, wchar_t, desired_size, DN_ZMem_No); if (!w_path) return result; @@ -9744,7 +9732,7 @@ DN_API DN_Str16 DN_W32_WorkingDirW(DN_Arena *arena, DN_Str16 suffix) w_path[desired_size] = 0; } - result = DN_Str16{w_path, DN_CAST(DN_USize)(desired_size - 1)}; + result = DN_Str16{w_path, DN_Cast(DN_USize)(desired_size - 1)}; return result; } @@ -9775,7 +9763,7 @@ DN_API bool DN_W32_DirWIterate(DN_Str16 path, DN_W32FolderIteratorW *it) if (find_data.cFileName[0] == '.' || (find_data.cFileName[0] == '.' && find_data.cFileName[1] == '.')) continue; - it->file_name.size = DN_CStr16_Size(find_data.cFileName); + it->file_name.size = DN_CStr16Size(find_data.cFileName); DN_Assert(it->file_name.size < (DN_ArrayCountU(it->file_name_buf) - 1)); DN_Memcpy(it->file_name.data, find_data.cFileName, it->file_name.size * sizeof(wchar_t)); it->file_name_buf[it->file_name.size] = 0; @@ -9804,19 +9792,19 @@ DN_API void DN_Core_Init(DN_Core *core, DN_CoreOnInit on_init) #if defined(DN_LEAK_TRACKING) // NOTE: Setup the allocation table with allocation tracking turned off on // the arena we're using to initialise the table. - core->alloc_table_arena = DN_Arena_FromVMem(DN_Megabytes(1), DN_Kilobytes(512), DN_ArenaFlags_NoAllocTrack | DN_ArenaFlags_AllocCanLeak); + core->alloc_table_arena = DN_ArenaFromVMem(DN_Megabytes(1), DN_Kilobytes(512), DN_ArenaFlags_NoAllocTrack | DN_ArenaFlags_AllocCanLeak); core->alloc_table = DN_DSMap_Init(&core->alloc_table_arena, 4096, DN_DSMapFlags_Nil); #endif // NOTE: Print out init features /////////////////////////////////////////////////////////////// DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr); - DN_Str8Builder builder = DN_Str8Builder_FromArena(tmem.arena); + DN_Str8Builder builder = DN_Str8BuilderFromArena(tmem.arena); if (on_init & DN_CoreOnInit_LogLibFeatures) { - DN_Str8Builder_AppendRef(&builder, DN_STR8("DN initialised:\n")); + DN_Str8BuilderAppendRef(&builder, DN_Str8Lit("DN initialised:\n")); DN_F32 page_size_kib = g_dn_os_core_->page_size / 1024.0f; DN_F32 alloc_granularity_kib = g_dn_os_core_->alloc_granularity / 1024.0f; - DN_Str8Builder_AppendF(&builder, + DN_Str8BuilderAppendF(&builder, " OS Page Size/Alloc Granularity: %.1f/%.1fKiB\n" " Logical Processor Count: %u\n", page_size_kib, @@ -9825,29 +9813,29 @@ DN_API void DN_Core_Init(DN_Core *core, DN_CoreOnInit on_init) #if DN_HAS_FEATURE(address_sanitizer) || defined(__SANITIZE_ADDRESS__) if (DN_ASAN_POISON) { - DN_Str8Builder_AppendF( + DN_Str8BuilderAppendF( &builder, " ASAN manual poisoning%s\n", DN_ASAN_VET_POISON ? " (+vet sanity checks)" : ""); - DN_Str8Builder_AppendF(&builder, " ASAN poison guard size: %u\n", DN_ASAN_POISON_GUARD_SIZE); + DN_Str8BuilderAppendF(&builder, " ASAN poison guard size: %u\n", DN_ASAN_POISON_GUARD_SIZE); } #endif #if defined(DN_LEAK_TRACKING) - DN_Str8Builder_AppendRef(&builder, DN_STR8(" Allocation leak tracing\n")); + DN_Str8BuilderAppendRef(&builder, DN_Str8Lit(" Allocation leak tracing\n")); #endif #if defined(DN_PLATFORM_EMSCRIPTEN) || defined(DN_PLATFORM_POSIX) - DN_POSIXCore *posix = DN_CAST(DN_POSIXCore *)g_dn_os_core_->platform_context; - DN_Str8Builder_AppendF(&builder, " Clock GetTime: %S\n", posix->clock_monotonic_raw ? DN_STR8("CLOCK_MONOTONIC_RAW") : DN_STR8("CLOCK_MONOTONIC")); + DN_POSIXCore *posix = DN_Cast(DN_POSIXCore *)g_dn_os_core_->platform_context; + DN_Str8BuilderAppendF(&builder, " Clock GetTime: %S\n", posix->clock_monotonic_raw ? DN_Str8Lit("CLOCK_MONOTONIC_RAW") : DN_Str8Lit("CLOCK_MONOTONIC")); #endif // TODO(doyle): Add stacktrace feature log } if (on_init & DN_CoreOnInit_LogCPUFeatures) { DN_CPUReport const *report = &g_dn_os_core_->cpu_report; - DN_Str8 brand = DN_Str8_TrimWhitespaceAround(DN_Str8_Init(report->brand, sizeof(report->brand) - 1)); + DN_Str8 brand = DN_Str8TrimWhitespaceAround(DN_Str8FromPtr(report->brand, sizeof(report->brand) - 1)); DN_MSVC_WARNING_PUSH - DN_MSVC_WARNING_DISABLE(6284) // Object passed as _Param_(3) when a string is required in call to 'DN_Str8Builder_AppendF' Actual type: 'struct DN_Str8'. - DN_Str8Builder_AppendF(&builder, " CPU '%S' from '%s' detected:\n", brand, report->vendor); + DN_MSVC_WARNING_DISABLE(6284) // Object passed as _Param_(3) when a string is required in call to 'DN_Str8BuilderAppendF' Actual type: 'struct DN_Str8'. + DN_Str8BuilderAppendF(&builder, " CPU '%S' from '%s' detected:\n", brand, report->vendor); DN_MSVC_WARNING_POP DN_USize longest_feature_name = 0; @@ -9859,18 +9847,18 @@ DN_API void DN_Core_Init(DN_Core *core, DN_CoreOnInit on_init) for (DN_ForIndexU(feature_index, DN_CPUFeature_Count)) { DN_CPUFeatureDecl feature_decl = g_dn_cpu_feature_decl[feature_index]; bool has_feature = DN_CPUHasFeature(report, feature_decl.value); - DN_Str8Builder_AppendF(&builder, + DN_Str8BuilderAppendF(&builder, " %.*s:%*s%s\n", - DN_STR_FMT(feature_decl.label), - DN_CAST(int)(longest_feature_name - feature_decl.label.size), + DN_Str8PrintFmt(feature_decl.label), + DN_Cast(int)(longest_feature_name - feature_decl.label.size), "", has_feature ? "available" : "not available"); } } - DN_Str8 info_log = DN_Str8Builder_Build(&builder, tmem.arena); - if (DN_Str8_HasData(info_log)) - DN_LOG_DebugF("%.*s", DN_STR_FMT(info_log)); + DN_Str8 info_log = DN_Str8BuilderBuild(&builder, tmem.arena); + if (info_log.size) + DN_LOG_DebugF("%.*s", DN_Str8PrintFmt(info_log)); } DN_API void DN_Core_BeginFrame() @@ -9904,7 +9892,7 @@ DN_API DN_StackTraceWalkResult DN_StackTrace_Walk(DN_Arena *arena, uint16_t limi if (!SymInitialize(result.process, nullptr /*UserSearchPath*/, true /*fInvadeProcess*/)) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena); DN_W32Error error = DN_W32_LastError(tmem.arena); - DN_LOG_ErrorF("SymInitialize failed, stack trace can not be generated (%lu): %.*s\n", error.code, DN_STR_FMT(error.msg)); + DN_LOG_ErrorF("SymInitialize failed, stack trace can not be generated (%lu): %.*s\n", error.code, DN_Str8PrintFmt(error.msg)); } } @@ -9938,8 +9926,8 @@ DN_API DN_StackTraceWalkResult DN_StackTrace_Walk(DN_Arena *arena, uint16_t limi } DN_TicketMutex_End(&mutex); - result.base_addr = DN_Arena_NewArray(arena, uint64_t, raw_frames.size, DN_ZeroMem_No); - result.size = DN_CAST(uint16_t) raw_frames.size; + result.base_addr = DN_ArenaNewArray(arena, uint64_t, raw_frames.size, DN_ZMem_No); + result.size = DN_Cast(uint16_t) raw_frames.size; DN_Memcpy(result.base_addr, raw_frames.data, raw_frames.size * sizeof(raw_frames.data[0])); #else (void)limit; @@ -9948,14 +9936,14 @@ DN_API DN_StackTraceWalkResult DN_StackTrace_Walk(DN_Arena *arena, uint16_t limi return result; } -static void DN_StackTrace_AddWalkToStr8Builder_(DN_StackTraceWalkResult const *walk, DN_Str8Builder *builder, DN_USize skip) +static void DN_StackTrace_AddWalkToStr8Builder(DN_StackTraceWalkResult const *walk, DN_Str8Builder *builder, DN_USize skip) { DN_StackTraceRawFrame raw_frame = {}; raw_frame.process = walk->process; for (DN_USize index = skip; index < walk->size; index++) { raw_frame.base_addr = walk->base_addr[index]; DN_StackTraceFrame frame = DN_StackTrace_RawFrameToFrame(builder->arena, raw_frame); - DN_Str8Builder_AppendF(builder, "%.*s(%zu): %.*s%s", DN_STR_FMT(frame.file_name), frame.line_number, DN_STR_FMT(frame.function_name), (DN_CAST(int) index == walk->size - 1) ? "" : "\n"); + DN_Str8BuilderAppendF(builder, "%.*s(%zu): %.*s%s", DN_Str8PrintFmt(frame.file_name), frame.line_number, DN_Str8PrintFmt(frame.function_name), (DN_Cast(int) index == walk->size - 1) ? "" : "\n"); } } @@ -9981,9 +9969,9 @@ DN_API DN_Str8 DN_StackTrace_WalkResultToStr8(DN_Arena *arena, DN_StackTraceWalk return result; DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena); - DN_Str8Builder builder = DN_Str8Builder_FromArena(tmem.arena); - DN_StackTrace_AddWalkToStr8Builder_(walk, &builder, skip); - result = DN_Str8Builder_Build(&builder, arena); + DN_Str8Builder builder = DN_Str8BuilderFromArena(tmem.arena); + DN_StackTrace_AddWalkToStr8Builder(walk, &builder, skip); + result = DN_Str8BuilderBuild(&builder, arena); return result; } @@ -9999,12 +9987,12 @@ DN_API DN_Str8 DN_StackTrace_WalkStr8FromHeap(uint16_t limit, uint16_t skip) { // NOTE: We don't use WalkResultToStr8 because that uses the TLS arenas which // does not use the OS heap. - DN_Arena arena = DN_Arena_FromHeap(DN_Kilobytes(64), DN_ArenaFlags_NoAllocTrack); - DN_Str8Builder builder = DN_Str8Builder_FromArena(&arena); + DN_Arena arena = DN_ArenaFromHeap(DN_Kilobytes(64), DN_ArenaFlags_NoAllocTrack); + DN_Str8Builder builder = DN_Str8BuilderFromArena(&arena); DN_StackTraceWalkResult walk = DN_StackTrace_Walk(&arena, limit); - DN_StackTrace_AddWalkToStr8Builder_(&walk, &builder, skip); - DN_Str8 result = DN_Str8Builder_BuildFromOSHeap(&builder); - DN_Arena_Deinit(&arena); + DN_StackTrace_AddWalkToStr8Builder(&walk, &builder, skip); + DN_Str8 result = DN_Str8BuilderBuildFromOSHeap(&builder); + DN_ArenaDeinit(&arena); return result; } @@ -10020,7 +10008,7 @@ DN_API DN_Slice DN_StackTrace_GetFrames(DN_Arena *arena, uin return result; DN_USize slice_index = 0; - result = DN_Slice_Alloc(arena, walk.size, DN_ZeroMem_No); + result = DN_Slice_Alloc(arena, walk.size, DN_ZMem_No); for (DN_StackTraceWalkResultIterator it = {}; DN_StackTrace_WalkResultIterate(&it, &walk); ) { result.data[slice_index++] = DN_StackTrace_RawFrameToFrame(arena, it.raw_frame); } @@ -10047,7 +10035,7 @@ DN_API DN_StackTraceFrame DN_StackTrace_RawFrameToFrame(DN_Arena *arena, DN_Stac // NOTE: Get function name ///////////////////////////////////////////////////////////////////// alignas(SYMBOL_INFOW) char buffer[sizeof(SYMBOL_INFOW) + (MAX_SYM_NAME * sizeof(wchar_t))] = {}; - SYMBOL_INFOW *symbol = DN_CAST(SYMBOL_INFOW *)buffer; + SYMBOL_INFOW *symbol = DN_Cast(SYMBOL_INFOW *)buffer; symbol->SizeOfStruct = sizeof(*symbol); symbol->MaxNameLen = sizeof(buffer) - sizeof(*symbol); @@ -10056,7 +10044,7 @@ DN_API DN_StackTraceFrame DN_StackTrace_RawFrameToFrame(DN_Arena *arena, DN_Stac // NOTE: Construct result ////////////////////////////////////////////////////////////////////// - DN_Str16 file_name16 = DN_Str16{line.FileName, DN_CStr16_Size(line.FileName)}; + DN_Str16 file_name16 = DN_Str16{line.FileName, DN_CStr16Size(line.FileName)}; DN_Str16 function_name16 = DN_Str16{symbol->Name, symbol->NameLen}; DN_StackTraceFrame result = {}; @@ -10065,10 +10053,10 @@ DN_API DN_StackTraceFrame DN_StackTrace_RawFrameToFrame(DN_Arena *arena, DN_Stac result.file_name = DN_W32_Str16ToStr8(arena, file_name16); result.function_name = DN_W32_Str16ToStr8(arena, function_name16); - if (!DN_Str8_HasData(result.function_name)) - result.function_name = DN_STR8(""); - if (!DN_Str8_HasData(result.file_name)) - result.file_name = DN_STR8(""); + if (result.function_name.size == 0) + result.function_name = DN_Str8Lit(""); + if (result.file_name.size == 0) + result.file_name = DN_Str8Lit(""); #else DN_StackTraceFrame result = {}; #endif @@ -10080,7 +10068,7 @@ DN_API void DN_StackTrace_Print(uint16_t limit) DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); DN_Slice stack_trace = DN_StackTrace_GetFrames(tmem.arena, limit); for (DN_StackTraceFrame &frame : stack_trace) - DN_OS_PrintErrLnF("%.*s(%I64u): %.*s", DN_STR_FMT(frame.file_name), frame.line_number, DN_STR_FMT(frame.function_name)); + DN_OS_PrintErrLnF("%.*s(%I64u): %.*s", DN_Str8PrintFmt(frame.file_name), frame.line_number, DN_Str8PrintFmt(frame.function_name)); } DN_API void DN_StackTrace_ReloadSymbols() @@ -10109,12 +10097,12 @@ DN_API void DN_DBGTrackAlloc(void *ptr, DN_USize size, bool leak_permitted) // already existed. DN_Str8 stack_trace = DN_StackTrace_WalkStr8FromHeap(128, 3 /*skip*/); DN_DSMap *alloc_table = &g_dn_core->alloc_table; - DN_DSMapResult alloc_entry = DN_DSMap_MakeKeyU64(alloc_table, DN_CAST(uint64_t) ptr); + DN_DSMapResult alloc_entry = DN_DSMap_MakeKeyU64(alloc_table, DN_Cast(uint64_t) ptr); DN_DebugAlloc *alloc = alloc_entry.value; if (alloc_entry.found) { if ((alloc->flags & DN_DebugAllocFlag_Freed) == 0) { - DN_Str8 alloc_size = DN_CVT_BytesStr8FromU64Auto(alloc_table->arena, alloc->size); - DN_Str8 new_alloc_size = DN_CVT_BytesStr8FromU64Auto(alloc_table->arena, size); + DN_Str8x32 alloc_size = DN_ByteCountStr8x32(alloc->size); + DN_Str8x32 new_alloc_size = DN_ByteCountStr8x32(size); DN_HardAssertF( alloc->flags & DN_DebugAllocFlag_Freed, "This pointer is already in the leak tracker, however it has not been freed yet. This " @@ -10130,10 +10118,10 @@ DN_API void DN_DBGTrackAlloc(void *ptr, DN_USize size, bool leak_permitted) "\n" "%.*s\n", ptr, - DN_STR_FMT(alloc_size), - DN_STR_FMT(alloc->stack_trace), - DN_STR_FMT(new_alloc_size), - DN_STR_FMT(stack_trace)); + DN_Str8PrintFmt(alloc_size), + DN_Str8PrintFmt(alloc->stack_trace), + DN_Str8PrintFmt(new_alloc_size), + DN_Str8PrintFmt(stack_trace)); } // NOTE: Pointer was reused, clean up the prior entry @@ -10162,7 +10150,7 @@ DN_API void DN_DBGTrackDealloc(void *ptr) DN_Str8 stack_trace = DN_StackTrace_WalkStr8FromHeap(128, 3 /*skip*/); DN_DSMap *alloc_table = &g_dn_core->alloc_table; - DN_DSMapResult alloc_entry = DN_DSMap_FindKeyU64(alloc_table, DN_CAST(uintptr_t) ptr); + DN_DSMapResult alloc_entry = DN_DSMap_FindKeyU64(alloc_table, DN_Cast(uintptr_t) ptr); DN_HardAssertF(alloc_entry.found, "Allocated pointer can not be removed as it does not exist in the " "allocation table. When this memory was allocated, the pointer was " @@ -10171,7 +10159,7 @@ DN_API void DN_DBGTrackDealloc(void *ptr) DN_DebugAlloc *alloc = alloc_entry.value; if (alloc->flags & DN_DebugAllocFlag_Freed) { - DN_Str8 freed_size = DN_CVT_BytesStr8FromU64Auto(alloc_table->arena, alloc->freed_size); + DN_Str8x32 freed_size = DN_ByteCountStr8x32(alloc->freed_size); DN_HardAssertF((alloc->flags & DN_DebugAllocFlag_Freed) == 0, "Double free detected, pointer to free was already marked " "as freed. Either the pointer was reallocated but not " @@ -10189,13 +10177,13 @@ DN_API void DN_DBGTrackDealloc(void *ptr) "\n" "%.*s\n" , - ptr, DN_STR_FMT(freed_size), - DN_STR_FMT(alloc->stack_trace), - DN_STR_FMT(alloc->freed_stack_trace), - DN_STR_FMT(stack_trace)); + ptr, DN_Str8PrintFmt(freed_size), + DN_Str8PrintFmt(alloc->stack_trace), + DN_Str8PrintFmt(alloc->freed_stack_trace), + DN_Str8PrintFmt(stack_trace)); } - DN_Assert(!DN_Str8_HasData(alloc->freed_stack_trace)); + DN_Assert(alloc->freed_stack_trace.size == 0); alloc->flags |= DN_DebugAllocFlag_Freed; alloc->freed_stack_trace = stack_trace; g_dn_core->alloc_table_bytes_allocated_for_stack_traces += alloc->freed_stack_trace.size; @@ -10213,19 +10201,17 @@ DN_API void DN_DBGDumpLeaks() if (alloc_leaked && !leak_permitted) { leaked_bytes += alloc->size; leak_count++; - DN_Str8 alloc_size = DN_CVT_BytesStr8FromU64Auto(g_dn_core->alloc_table.arena, alloc->size); + DN_Str8x32 alloc_size = DN_ByteCountStr8x32(alloc->size); DN_LOG_WarningF("Pointer (0x%p) leaked %.*s at:\n" "%.*s", - alloc->ptr, DN_STR_FMT(alloc_size), - DN_STR_FMT(alloc->stack_trace)); + alloc->ptr, DN_Str8PrintFmt(alloc_size), + DN_Str8PrintFmt(alloc->stack_trace)); } } if (leak_count) { - char buffer[512]; - DN_Arena arena = DN_Arena_FromBuffer(buffer, sizeof(buffer), DN_ArenaFlags_Nil); - DN_Str8 leak_size = DN_CVT_BytesStr8FromU64Auto(&arena, leaked_bytes); - DN_LOG_WarningF("There were %I64u leaked allocations totalling %.*s", leak_count, DN_STR_FMT(leak_size)); + DN_Str8x32 leak_size = DN_ByteCountStr8x32(leaked_bytes); + DN_LOG_WarningF("There were %I64u leaked allocations totalling %.*s", leak_count, DN_Str8PrintFmt(leak_size)); } } #endif // DN_LEAK_TRACKING @@ -10276,8 +10262,8 @@ DN_API DN_ProfilerZone DN_Profiler_BeginZone(DN_Profiler *profiler, DN_Str8 name // TODO: We need per-thread-local-storage profiler so that we can use these apis // across threads. For now, we let them overwrite each other but this is not tenable. #if 0 - if (DN_Str8_HasData(anchor->name) && anchor->name != name) - DN_AssertF(name == anchor->name, "Potentially overwriting a zone by accident? Anchor is '%.*s', name is '%.*s'", DN_STR_FMT(anchor->name), DN_STR_FMT(name)); + if (anchor->name.size && anchor->name != name) + DN_AssertF(name == anchor->name, "Potentially overwriting a zone by accident? Anchor is '%.*s', name is '%.*s'", DN_Str8PrintFmt(anchor->name), DN_Str8PrintFmt(name)); #endif if (profiler->tsc == DN_ProfilerTSC_RDTSC) @@ -10335,7 +10321,7 @@ DN_API void DN_Profiler_NewFrame(DN_Profiler *profiler) DN_Memset(next_anchors.data, 0, sizeof(*profiler->anchors) * next_anchors.count); // NOTE: Start the frame's zone - profiler->frame_zone = DN_Profiler_BeginZone(profiler, DN_STR8("Profiler Frame"), 0); + profiler->frame_zone = DN_Profiler_BeginZone(profiler, DN_Str8Lit("Profiler Frame"), 0); } DN_API void DN_Profiler_Dump(DN_Profiler *profiler) @@ -10354,13 +10340,13 @@ DN_API void DN_Profiler_Dump(DN_Profiler *profiler) DN_U64 tsc_exclusive = anchor->tsc_exclusive; DN_U64 tsc_inclusive = anchor->tsc_inclusive; - DN_F64 tsc_exclusive_milliseconds = tsc_exclusive * 1000 / DN_CAST(DN_F64) profiler->tsc_frequency; + DN_F64 tsc_exclusive_milliseconds = tsc_exclusive * 1000 / DN_Cast(DN_F64) profiler->tsc_frequency; if (tsc_exclusive == tsc_inclusive) { - DN_OS_PrintOutLnF("%.*s[%u]: %.1fms", DN_STR_FMT(anchor->name), anchor->hit_count, tsc_exclusive_milliseconds); + DN_OS_PrintOutLnF("%.*s[%u]: %.1fms", DN_Str8PrintFmt(anchor->name), anchor->hit_count, tsc_exclusive_milliseconds); } else { - DN_F64 tsc_inclusive_milliseconds = tsc_inclusive * 1000 / DN_CAST(DN_F64) profiler->tsc_frequency; + DN_F64 tsc_inclusive_milliseconds = tsc_inclusive * 1000 / DN_Cast(DN_F64) profiler->tsc_frequency; DN_OS_PrintOutLnF("%.*s[%u]: %.1f/%.1fms", - DN_STR_FMT(anchor->name), + DN_Str8PrintFmt(anchor->name), anchor->hit_count, tsc_exclusive_milliseconds, tsc_inclusive_milliseconds); @@ -10370,13 +10356,13 @@ DN_API void DN_Profiler_Dump(DN_Profiler *profiler) DN_API DN_F64 DN_Profiler_SecFromTSC(DN_Profiler *profiler, DN_U64 duration_tsc) { - DN_F64 result = DN_CAST(DN_F64)duration_tsc / profiler->tsc_frequency; + DN_F64 result = DN_Cast(DN_F64)duration_tsc / profiler->tsc_frequency; return result; } DN_API DN_F64 DN_Profiler_MsFromTSC(DN_Profiler *profiler, DN_U64 duration_tsc) { - DN_F64 result = DN_CAST(DN_F64)duration_tsc / profiler->tsc_frequency * 1000.0; + DN_F64 result = DN_Cast(DN_F64)duration_tsc / profiler->tsc_frequency * 1000.0; return result; } // DN: Single header generator inlined this file => #include "Core/dn_core_demo.cpp" @@ -10421,8 +10407,8 @@ void DN_Docs_Demo() DN_Core_Init(&core, DN_CoreOnInit_Nil); #endif - // NOTE: DN_AtomicSetValue64 ///////////////////////////////////////////////////////////////// - // NOTE: DN_AtomicSetValue32 ///////////////////////////////////////////////////////////////// + // NOTE: DN_AtomicSetValue64 + // NOTE: DN_AtomicSetValue32 // Atomically set the value into the target using an atomic compare and swap // idiom. The return value of the function is the value that was last stored // in the target. @@ -10436,15 +10422,24 @@ void DN_Docs_Demo() } } - // NOTE: DN_CVT_HexFromBytes //////////////////////////////////////////////////////////////////////// + // NOTE: DN_HexFromBytes { - DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); + DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); unsigned char bytes[2] = {0xFA, 0xCE}; - DN_Str8 hex = DN_CVT_HexFromBytes(tmem.arena, bytes, sizeof(bytes)); - DN_Assert(hex == DN_STR8("face")); // NOTE: Guaranteed to be null-terminated + DN_Str8 hex = DN_HexFromBytesPtrArena(bytes, sizeof(bytes), tmem.arena); + DN_Assert(DN_Str8Eq(hex, DN_Str8Lit("face"))); // NOTE: Guaranteed to be null-terminated } - // NOTE: DN_Check ///////////////////////////////////////////////////////////////////////////// + // NOTE: DN_BytesFromHex + { + unsigned char bytes[2]; + DN_USize bytes_written = DN_BytesFromHexStr8(DN_Str8Lit("0xFACE"), bytes, sizeof(bytes)); + DN_Assert(bytes_written == 2); + DN_Assert(bytes[0] == 0xFA); + DN_Assert(bytes[1] == 0xCE); + } + + // NOTE: DN_Check // // Check the expression trapping in debug, whilst in release- trapping is // removed and the expression is evaluated as if it were a normal 'if' branch. @@ -10458,7 +10453,7 @@ void DN_Docs_Demo() } } - // NOTE: DN_CPUID ///////////////////////////////////////////////////////////////////////////// + // NOTE: DN_CPUID // Execute the 'CPUID' instruction which lets you query the capabilities of // the current CPU. @@ -10476,7 +10471,7 @@ void DN_Docs_Demo() // On scope exit, DN_DEFER object executes and assigns x = 3 } - // NOTE: DN_DSMap ///////////////////////////////////////////////////////////////////////////// + // NOTE: DN_DSMap // // A hash table configured using the presets recommended by Demitri Spanos // from the Handmade Network (HMN), @@ -10517,8 +10512,8 @@ void DN_Docs_Demo() // buffer, this buffer must be valid throughout the lifetime of the hash // table! { - // NOTE: DN_DSMap_Init ////////////////////////////////////////////////////////////////// - // NOTE: DN_DSMap_Deinit ////////////////////////////////////////////////////////////////// + // NOTE: DN_DSMap_Init + // NOTE: DN_DSMap_Deinit // // Initialise a hash table where the table size *must* be a // power-of-two, otherwise an assert will be triggered. If @@ -10536,16 +10531,16 @@ void DN_Docs_Demo() // // A 'Deinit' of the map will similarly deallocate the passed in arena (as // the map takes ownership of the arena). - DN_Arena arena = DN_Arena_FromVMem(0, 0, DN_ArenaFlags_Nil); + DN_Arena arena = DN_ArenaFromVMem(0, 0, DN_ArenaFlags_Nil); DN_DSMap map = DN_DSMap_Init(&arena, /*size*/ 1024, DN_DSMapFlags_Nil); // Size must be PoT! DN_Assert(DN_DSMap_IsValid(&map)); // Valid if no initialisation failure (e.g. mem alloc failure) - // NOTE: DN_DSMap_KeyCStringLit /////////////////////////////////////////////////////////// - // NOTE: DN_DSMap_KeyU64 /////////////////////////////////////////////////////////// - // NOTE: DN_DSMap_KeyU64NoHash /////////////////////////////////////////////////////////// - // NOTE: DN_DSMap_KeyBuffer /////////////////////////////////////////////////////////// - // NOTE: DN_DSMap_KeyStr8 /////////////////////////////////////////////////////////// - // NOTE: DN_DSMap_KeyStr8Copy /////////////////////////////////////////////////////////// + // NOTE: DN_DSMap_KeyCStringLit + // NOTE: DN_DSMap_KeyU64 + // NOTE: DN_DSMap_KeyU64NoHash + // NOTE: DN_DSMap_KeyBuffer + // NOTE: DN_DSMap_KeyStr8 + // NOTE: DN_DSMap_KeyStr8Copy // Create a hash-table key where: // // KeyCStringLit: Uses a Hash(cstring literal) @@ -10566,11 +10561,11 @@ void DN_Docs_Demo() // already sufficiently uniformly distributed already (e.g. using 8 // bytes taken from a SHA256 hash as the key) and the first 4 bytes // will be used verbatim. - DN_DSMapKey key = DN_DSMap_KeyStr8(&map, DN_STR8("Sample Key")); + DN_DSMapKey key = DN_DSMap_KeyStr8(&map, DN_Str8Lit("Sample Key")); - // NOTE: DN_DSMap_Find //////////////////////////////////////////////////////////////////// - // NOTE: DN_DSMap_Make //////////////////////////////////////////////////////////////////// - // NOTE: DN_DSMap_Set //////////////////////////////////////////////////////////////////// + // NOTE: DN_DSMap_Find + // NOTE: DN_DSMap_Make + // NOTE: DN_DSMap_Set // // Query or commit key-value pair to the table, where: // @@ -10601,10 +10596,10 @@ void DN_Docs_Demo() int *it_value = &it->value; DN_Assert(*it_value == 0xCAFE); - DN_Assert(DN_Str8_Init(it_key.buffer_data, it_key.buffer_size) == DN_STR8("Sample Key")); + DN_Assert(DN_Str8Eq(DN_Str8FromPtr(it_key.buffer_data, it_key.buffer_size), DN_Str8Lit("Sample Key"))); } - // NOTE: DN_DSMap_Erase /////////////////////////////////////////////////////////////////// + // NOTE: DN_DSMap_Erase // // Remove the key-value pair from the table. If by erasing the key-value // pair from the table puts the table under 25% load, the table will be @@ -10616,26 +10611,26 @@ void DN_Docs_Demo() DN_Assert(map.occupied == 1); // Sentinel element } - DN_DSMap_Deinit(&map, DN_ZeroMem_Yes); // Deallocates the 'arena' for us! + DN_DSMap_Deinit(&map, DN_ZMem_Yes); // Deallocates the 'arena' for us! } -// NOTE: DN_DSMap_Hash //////////////////////////////////////////////////////////////////////// +// NOTE: DN_DSMap_Hash // // Hash the input key using the custom hash function if it's set on the map, // otherwise uses the default hashing function (32bit Murmur3). -// NOTE: DN_DSMap_HashToSlotIndex ///////////////////////////////////////////////////////////// +// NOTE: DN_DSMap_HashToSlotIndex // // Calculate the index into the map's 'slots' array from the given hash. -// NOTE: DN_DSMap_Resize ////////////////////////////////////////////////////////////////////// +// NOTE: DN_DSMap_Resize // // Resize the table and move all elements to the new map, note that the new // size must be a power of two. This function wil fail on memory allocation // failure, or the requested size is smaller than the current number of // elements in the map to resize. -// NOTE: DN_OSErrSink ///////////////////////////////////////////////////////////////////////// +// NOTE: DN_OSErrSink // // Error sinks are a way of accumulating errors from API calls related or // unrelated into 1 unified error handling pattern. The implemenation of a @@ -10672,8 +10667,8 @@ void DN_Docs_Demo() // produce errors take in the error sink as a parameter. if (0) { DN_OSErrSink *error = DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil); - DN_OSFile file = DN_OS_FileOpen(DN_STR8("/path/to/file"), DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_ReadWrite, error); - DN_OS_FileWrite(&file, DN_STR8("abc"), error); + DN_OSFile file = DN_OS_FileOpen(DN_Str8Lit("/path/to/file"), DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_ReadWrite, error); + DN_OS_FileWrite(&file, DN_Str8Lit("abc"), error); DN_OS_FileClose(&file); if (DN_OS_ErrSinkEndAndLogErrorF(error, "Failed to write to file")) { // Do error handling! @@ -10696,15 +10691,15 @@ void DN_Docs_Demo() if (0) { DN_OSErrSink *error = DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil); - DN_OSFile file = DN_OS_FileOpen(DN_STR8("/path/to/file"), DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_ReadWrite, error); - DN_OS_FileWrite(&file, DN_STR8("abc"), error); + DN_OSFile file = DN_OS_FileOpen(DN_Str8Lit("/path/to/file"), DN_OSFileOpen_OpenIfExist, DN_OSFileAccess_ReadWrite, error); + DN_OS_FileWrite(&file, DN_Str8Lit("abc"), error); DN_OS_FileClose(&file); { // NOTE: My error sinks are thread-local, so the returned 'error' is // the same as the 'error' value above. DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil); - DN_OS_FileWriteAll(DN_STR8("/path/to/another/file"), DN_STR8("123"), error); + DN_OS_FileWriteAll(DN_Str8Lit("/path/to/another/file"), DN_Str8Lit("123"), error); DN_OS_ErrSinkEndAndLogErrorF(error, "Failed to write to another file"); } @@ -10713,16 +10708,7 @@ void DN_Docs_Demo() } } - // NOTE: DN_CVT_BytesFromHex //////////////////////////////////////////////////////////////////////// - { - unsigned char bytes[2]; - DN_USize bytes_written = DN_CVT_BytesFromHexPtr(DN_STR8("0xFACE"), bytes, sizeof(bytes)); - DN_Assert(bytes_written == 2); - DN_Assert(bytes[0] == 0xFA); - DN_Assert(bytes[1] == 0xCE); - } - - // NOTE: DN_JSONBuilder_Build ///////////////////////////////////////////////////////////////// + // NOTE: DN_JSONBuilder_Build // // Convert the internal JSON buffer in the builder into a string. @@ -10748,14 +10734,14 @@ void DN_Docs_Demo() // the following '"": ' (e.g. useful for emitting the 'null' // value) - // NOTE: DN_JSONBuilder_U64 ///////////////////////////////////////////////////////////// - // NOTE: DN_JSONBuilder_U64Named ///////////////////////////////////////////////////////////// - // NOTE: DN_JSONBuilder_I64 ///////////////////////////////////////////////////////////// - // NOTE: DN_JSONBuilder_I64Named ///////////////////////////////////////////////////////////// - // NOTE: DN_JSONBuilder_F64 ///////////////////////////////////////////////////////////// - // NOTE: DN_JSONBuilder_F64Named ///////////////////////////////////////////////////////////// - // NOTE: DN_JSONBuilder_Bool ///////////////////////////////////////////////////////////// - // NOTE: DN_JSONBuilder_BoolNamed ///////////////////////////////////////////////////////////// + // NOTE: DN_JSONBuilder_U64 + // NOTE: DN_JSONBuilder_U64Named + // NOTE: DN_JSONBuilder_I64 + // NOTE: DN_JSONBuilder_I64Named + // NOTE: DN_JSONBuilder_F64 + // NOTE: DN_JSONBuilder_F64Named + // NOTE: DN_JSONBuilder_Bool + // NOTE: DN_JSONBuilder_BoolNamed // // Add the named JSON data type as a key-value object. The named variants // generates internally the key-value pair, e.g. @@ -10764,7 +10750,7 @@ void DN_Docs_Demo() // // And the non-named version emit just the 'value' portion - // NOTE: DN_List_Iterate ////////////////////////////////////////////////////////////////////// + // NOTE: DN_List_Iterate { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); DN_List list = DN_List_Init(/*chunk_size*/ 128); @@ -10774,13 +10760,13 @@ void DN_Docs_Demo() } } - // NOTE: DN_LOGProc /////////////////////////////////////////////////////////////////////////// + // NOTE: DN_LOGProc // // Function prototype of the logging interface exposed by this library. Logs // emitted using the DN_LOG_* family of functions are routed through this // routine. - // NOTE: DN_FNV1A ///////////////////////////////////////////////////////////////////////////// + // NOTE: DN_FNV1A #if 0 { // Using the default hash as defined by DN_FNV1A32_SEED and @@ -10804,15 +10790,7 @@ void DN_Docs_Demo() } #endif - // NOTE: DN_FmtBuffer3DotTruncate ////////////////////////////////////////////////////////////// - { - char buffer[8] = {}; - int buffer_chars_written = DN_CVT_FmtBuffer3DotTruncate(buffer, sizeof(buffer), "This string is longer than %d characters", DN_CAST(int)(sizeof(buffer) - 1)); - if (0) // Prints "This ..." which is exactly 8 characters long - printf("%.*s", buffer_chars_written, buffer); - } - - // NOTE: DN_MurmurHash3 /////////////////////////////////////////////////////////////////////// + // NOTE: DN_MurmurHash3 // MurmurHash3 was written by Austin Appleby, and is placed in the public // domain. The author (Austin Appleby) hereby disclaims copyright to this source // code. @@ -10830,11 +10808,11 @@ void DN_Docs_Demo() (void)now; } - // NOTE: DN_OS_DirIterate ///////////////////////////////////////////////////////////////////// + // NOTE: DN_OS_DirIterate // // Iterate the files within the passed in folder - for (DN_OSDirIterator it = {}; DN_OS_PathIterateDir(DN_STR8("."), &it);) { - // printf("%.*s\n", DN_STR_FMT(it.file_name)); + for (DN_OSDirIterator it = {}; DN_OS_PathIterateDir(DN_Str8Lit("."), &it);) { + // printf("%.*s\n", DN_Str8PrintFmt(it.file_name)); } // NOTE: DN_OS_FileDelete @@ -10855,11 +10833,11 @@ void DN_Docs_Demo() if (0) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); DN_OSErrSink *error = DN_OS_ErrSinkBegin(DN_OSErrSinkMode_Nil); - DN_OS_FileWriteAllSafe(/*path*/ DN_STR8("C:/Home/my.txt"), /*buffer*/ DN_STR8("Hello world"), error); + DN_OS_FileWriteAllSafe(/*path*/ DN_Str8Lit("C:/Home/my.txt"), /*buffer*/ DN_Str8Lit("Hello world"), error); DN_OS_ErrSinkEndAndLogErrorF(error, ""); } - // NOTE: DN_OS_EstimateTSCPerSecond /////////////////////////////////////////////////////////// + // NOTE: DN_OS_EstimateTSCPerSecond // // Estimate how many timestamp count's (TSC) there are per second. TSC // is evaluated by calling __rdtsc() or the equivalent on the platform. This @@ -10873,18 +10851,18 @@ void DN_Docs_Demo() // This may return 0 if querying the CPU timestamp counter is not supported // on the platform (e.g. __rdtsc() or __builtin_readcyclecounter() returns 0). - // NOTE: DN_OS_EXEDir ///////////////////////////////////////////////////////////////////////// + // NOTE: DN_OS_EXEDir // // Retrieve the executable directory without the trailing '/' or ('\' for // windows). If this fails an empty string is returned. - // NOTE: DN_OS_PerfCounterFrequency /////////////////////////////////////////////////////////// + // NOTE: DN_OS_PerfCounterFrequency // // Get the number of ticks in the performance counter per second for the // operating system you're running on. This value can be used to calculate // duration from OS performance counter ticks. - // NOTE: DN_OS_Path* ////////////////////////////////////////////////////////////////////////// + // NOTE: DN_OS_Path* // Construct paths ensuring the native OS path separators are used in the // string. In 99% of cases you can use 'PathConvertF' which converts the // given path in one shot ensuring native path separators in the string. @@ -10913,12 +10891,12 @@ void DN_Docs_Demo() // path: path/to/your/desired/folder // popped_path: path/to/your/desired - // NOTE: DN_OS_SecureRNGBytes ///////////////////////////////////////////////////////////////// + // NOTE: DN_OS_SecureRNGBytes // // Generate cryptographically secure bytes #if 0 - // NOTE: DN_PCG32 ///////////////////////////////////////////////////////////////////////////// + // NOTE: DN_PCG32 // // Random number generator of the PCG family. Implementation taken from // Martins Mmozeiko from Handmade Network. @@ -10926,20 +10904,20 @@ void DN_Docs_Demo() { DN_PCG32 rng = DN_PCG32_Init(0xb917'a66c'1d9b'3bd8); - // NOTE: DN_PCG32_Range /////////////////////////////////////////////////////////////////// + // NOTE: DN_PCG32_Range // // Generate a value in the [low, high) interval uint32_t u32_value = DN_PCG32_Range(&rng, 32, 64); DN_Assert(u32_value >= 32 && u32_value < 64); - // NOTE: DN_PCG32_NextF32 ///////////////////////////////////////////////////////////////// - // NOTE: DN_PCG32_NextF64 ///////////////////////////////////////////////////////////////// + // NOTE: DN_PCG32_NextF32 + // NOTE: DN_PCG32_NextF64 // // Generate a float/double in the [0, 1) interval DN_F64 f64_value = DN_PCG32_NextF64(&rng); DN_Assert(f64_value >= 0.f && f64_value < 1.f); - // NOTE: DN_PCG32_Advance ///////////////////////////////////////////////////////////////// + // NOTE: DN_PCG32_Advance // // Step the random number generator by 'delta' steps DN_PCG32_Advance(&rng, /*delta*/ 5); @@ -10948,7 +10926,7 @@ void DN_Docs_Demo() #if 0 #if !defined(DN_NO_PROFILER) - // NOTE: DN_Profiler ///////////////////////////////////////////////////////////////////////////// + // NOTE: DN_Profiler // // A profiler based off Casey Muratori's Computer Enhance course, Performance // Aware Programming. This profiler measures function elapsed time using the @@ -10969,7 +10947,7 @@ void DN_Docs_Demo() DN_ProfilerZone profiler_zone_main_update = DN_Profiler_BeginZone(Zone_MainLoop); - // NOTE: DN_Profiler_AnchorBuffer ///////////////////////////////////////////////////// + // NOTE: DN_Profiler_AnchorBuffer // // Retrieve the requested buffer from the profiler for // writing/reading profiling metrics. Pass in the enum to specify @@ -10983,7 +10961,7 @@ void DN_Docs_Demo() // the front buffer which contain the metrics that you can visualise // regarding the most profiling metrics recorded. - // NOTE: DN_Profiler_ReadBuffer /////////////////////////////////////////////////////////// + // NOTE: DN_Profiler_ReadBuffer // // Retrieve the buffer of anchors of which there are // `DN_PROFILER_ANCHOR_BUFFER_SIZE` anchors from the most recent run @@ -10992,19 +10970,19 @@ void DN_Docs_Demo() DN_ProfilerAnchor *read_anchors = DN_Profiler_ReadBuffer(); for (DN_USize index = 0; index < DN_PROFILER_ANCHOR_BUFFER_SIZE; index++) { DN_ProfilerAnchor *anchor = read_anchors + index; - if (DN_Str8_HasData(anchor->name)) { + if (anchor->name.size) { // ... } } - // NOTE: DN_Profiler_WriteBuffer ////////////////////////////////////////////////////////// + // NOTE: DN_Profiler_WriteBuffer // // Same as `ReadBuffer` however we return the buffer that the profiler // is currently writing anchors into. DN_ProfilerAnchor *write_anchors = DN_Profiler_WriteBuffer(); for (DN_USize index = 0; index < DN_PROFILER_ANCHOR_BUFFER_SIZE; index++) { DN_ProfilerAnchor *anchor = write_anchors + index; - if (DN_Str8_HasData(anchor->name)) { + if (anchor->name.size) { // ... } } @@ -11016,7 +10994,7 @@ void DN_Docs_Demo() #endif // !defined(DN_NO_PROFILER) #endif - // NOTE: DN_Raycast_LineIntersectV2 /////////////////////////////////////////////////////////// + // NOTE: DN_Raycast_LineIntersectV2 // Calculate the intersection point of 2 rays returning a `t` value // which is how much along the direction of the 'ray' did the intersection // occur. @@ -11024,14 +11002,14 @@ void DN_Docs_Demo() // The arguments passed in do not need to be normalised for the function to // work. - // NOTE: DN_Safe_* //////////////////////////////////////////////////////////////////////////// + // NOTE: DN_Safe_* // // Performs the arithmetic operation and uses DN_Check on the operation to // check if it overflows. If it overflows the MAX value of the integer is // returned in add and multiply operations, and, the minimum is returned in // subtraction and division. - // NOTE: DN_SaturateCast* //////////////////////////////////////////////////////////////// + // NOTE: DN_SaturateCast* // // Truncate the passed in value to the return type clamping the resulting // value to the max value of the desired data type. It DN_Check's the @@ -11078,7 +11056,7 @@ void DN_Docs_Demo() // Int -> U32: 0 or UINT32_MAX // Int -> U64: 0 or UINT64_MAX - // NOTE: DN_StackTrace //////////////////////////////////////////////////////////////////////// + // NOTE: DN_StackTrace // Emit stack traces at the calling site that these functions are invoked // from. // @@ -11097,7 +11075,7 @@ void DN_Docs_Demo() { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - // NOTE: DN_StackTrace_Walk /////////////////////////////////////////////////////////////// + // NOTE: DN_StackTrace_Walk // // Generate a stack trace as a series of addresses to the base of the // functions on the call-stack at the current instruction pointer. The @@ -11107,7 +11085,7 @@ void DN_Docs_Demo() // Loop over the addresses produced in the stack trace for (DN_StackTraceWalkResultIterator it = {}; DN_StackTrace_WalkResultIterate(&it, &walk);) { - // NOTE: DN_StackTrace_RawFrameToFrame //////////////////////////////////////////////// + // NOTE: DN_StackTrace_RawFrameToFrame // // Converts the base address into a human readable stack trace // entry (e.g. address, line number, file and function name). @@ -11115,7 +11093,7 @@ void DN_Docs_Demo() // You may then print out the frame like so if (0) - printf("%.*s(%" PRIu64 "): %.*s\n", DN_STR_FMT(frame.file_name), frame.line_number, DN_STR_FMT(frame.function_name)); + printf("%.*s(%" PRIu64 "): %.*s\n", DN_Str8PrintFmt(frame.file_name), frame.line_number, DN_Str8PrintFmt(frame.function_name)); } // If you load new shared-libraries into the address space it maybe @@ -11123,7 +11101,7 @@ void DN_Docs_Demo() // to resolve the new addresses. DN_StackTrace_ReloadSymbols(); - // NOTE: DN_StackTrace_GetFrames ////////////////////////////////////////////////////////// + // NOTE: DN_StackTrace_GetFrames // // Helper function to create a stack trace and automatically convert the // raw frames into human readable frames. This function effectively @@ -11132,7 +11110,7 @@ void DN_Docs_Demo() (void)frames; } - // NOTE: DN_Str8_Alloc //////////////////////////////////////////////////////////////////////// + // NOTE: DN_Str8FromArena // // Allocates a string with the requested 'size'. An additional byte is // always requested from the allocator to null-terminate the buffer. This @@ -11142,33 +11120,33 @@ void DN_Docs_Demo() // additional null-terminating byte. { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 string = DN_Str8_Alloc(tmem.arena, /*size*/ 1, DN_ZeroMem_Yes); + DN_Str8 string = DN_Str8FromArena(tmem.arena, /*size*/ 1, DN_ZMem_Yes); DN_Assert(string.size == 1); DN_Assert(string.data[string.size] == 0); // It is null-terminated! } - // NOTE: DN_Str8_BSplit ////////////////////////////////////////////////////////////////// + // NOTE: DN_Str8BSplit // // Splits a string into 2 substrings occuring prior and after the first // occurence of the delimiter. Neither strings include the matched // delimiter. If no delimiter is found, the 'rhs' of the split will be // empty. { - DN_Str8BSplitResult dot_split = DN_Str8_BSplit(/*string*/ DN_STR8("abc.def.ghi"), /*delimiter*/ DN_STR8(".")); - DN_Str8BSplitResult slash_split = DN_Str8_BSplit(/*string*/ DN_STR8("abc.def.ghi"), /*delimiter*/ DN_STR8("/")); - DN_Assert(dot_split.lhs == DN_STR8("abc") && dot_split.rhs == DN_STR8("def.ghi")); - DN_Assert(slash_split.lhs == DN_STR8("abc.def.ghi") && slash_split.rhs == DN_STR8("")); + DN_Str8BSplitResult dot_split = DN_Str8BSplit(/*string*/ DN_Str8Lit("abc.def.ghi"), /*delimiter*/ DN_Str8Lit(".")); + DN_Str8BSplitResult slash_split = DN_Str8BSplit(/*string*/ DN_Str8Lit("abc.def.ghi"), /*delimiter*/ DN_Str8Lit("/")); + DN_Assert(DN_Str8Eq(dot_split.lhs, DN_Str8Lit("abc")) && DN_Str8Eq(dot_split.rhs, DN_Str8Lit("def.ghi"))); + DN_Assert(DN_Str8Eq(slash_split.lhs, DN_Str8Lit("abc.def.ghi")) && DN_Str8Eq(slash_split.rhs, DN_Str8Lit(""))); // Loop that walks the string and produces ("abc", "def", "ghi") - for (DN_Str8 it = DN_STR8("abc.def.ghi"); it.size;) { - DN_Str8BSplitResult split = DN_Str8_BSplit(it, DN_STR8(".")); + for (DN_Str8 it = DN_Str8Lit("abc.def.ghi"); it.size;) { + DN_Str8BSplitResult split = DN_Str8BSplit(it, DN_Str8Lit(".")); DN_Str8 chunk = split.lhs; // "abc", "def", ... it = split.rhs; (void)chunk; } } - // NOTE: DN_Str8_FileNameFromPath ///////////////////////////////////////////////////////////// + // NOTE: DN_Str8FileNameFromPath // // Takes a slice to the file name from a file path. The file name is // evaluated by searching from the end of the string backwards to the first @@ -11177,41 +11155,41 @@ void DN_Docs_Demo() // if there were any. { { - DN_Str8 string = DN_Str8_FileNameFromPath(DN_STR8("C:/Folder/item.txt")); - DN_Assert(string == DN_STR8("item.txt")); + DN_Str8 string = DN_Str8FileNameFromPath(DN_Str8Lit("C:/Folder/item.txt")); + DN_Assert(DN_Str8Eq(string, DN_Str8Lit("item.txt"))); } { // TODO(doyle): Intuitively this seems incorrect. Empty string instead? - DN_Str8 string = DN_Str8_FileNameFromPath(DN_STR8("C:/Folder/")); - DN_Assert(string == DN_STR8("C:/Folder")); + DN_Str8 string = DN_Str8FileNameFromPath(DN_Str8Lit("C:/Folder/")); + DN_Assert(DN_Str8Eq(string, DN_Str8Lit("C:/Folder"))); } { - DN_Str8 string = DN_Str8_FileNameFromPath(DN_STR8("C:/Folder")); - DN_Assert(string == DN_STR8("Folder")); + DN_Str8 string = DN_Str8FileNameFromPath(DN_Str8Lit("C:/Folder")); + DN_Assert(DN_Str8Eq(string, DN_Str8Lit("Folder"))); } } - // NOTE: DN_Str8_FilePathNoExtension ////////////////////////////////////////////////////////// + // NOTE: DN_Str8FilePathNoExtension // // This function preserves the original string if no extension was found. // An extension is defined as the substring after the last '.' encountered // in the string. { - DN_Str8 string = DN_Str8_FilePathNoExtension(DN_STR8("C:/Folder/item.txt.bak")); - DN_Assert(string == DN_STR8("C:/Folder/item.txt")); + DN_Str8 string = DN_Str8FilePathNoExtension(DN_Str8Lit("C:/Folder/item.txt.bak")); + DN_Assert(DN_Str8Eq(string, DN_Str8Lit("C:/Folder/item.txt"))); } - // NOTE: DN_Str8_FileNameNoExtension ////////////////////////////////////////////////////////// + // NOTE: DN_Str8FileNameNoExtension // // This function is the same as calling 'FileNameFromPath' followed by // 'FilePathNoExtension' { - DN_Str8 string = DN_Str8_FileNameNoExtension(DN_STR8("C:/Folder/item.txt.bak")); - DN_Assert(string == DN_STR8("item.txt")); + DN_Str8 string = DN_Str8FileNameNoExtension(DN_Str8Lit("C:/Folder/item.txt.bak")); + DN_Assert(DN_Str8Eq(string, DN_Str8Lit("item.txt"))); } - // NOTE: DN_Str8_Replace /////////////////////////////////////////////////////////// - // NOTE: DN_Str8_ReplaceInsensitive /////////////////////////////////////////////////////////// + // NOTE: DN_Str8Replace + // NOTE: DN_Str8ReplaceInsensitive // // Replace any matching substring 'find' with 'replace' in the passed in // 'string'. The 'start_index' may be specified to offset which index the @@ -11222,16 +11200,16 @@ void DN_Docs_Demo() // were done or not. { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 string = DN_Str8_Replace(/*string*/ DN_STR8("Foo Foo Bar"), - /*find*/ DN_STR8("Foo"), - /*replace*/ DN_STR8("Moo"), + DN_Str8 string = DN_Str8Replace(/*string*/ DN_Str8Lit("Foo Foo Bar"), + /*find*/ DN_Str8Lit("Foo"), + /*replace*/ DN_Str8Lit("Moo"), /*start_index*/ 1, /*arena*/ tmem.arena, /*eq_case*/ DN_Str8EqCase_Sensitive); - DN_Assert(string == DN_STR8("Foo Moo Bar")); + DN_Assert(DN_Str8Eq(string, DN_Str8Lit("Foo Moo Bar"))); } - // NOTE: DN_Str8_Segment ////////////////////////////////////////////////////////////////////// + // NOTE: DN_Str8Segment // // Add a delimiting 'segment_char' every 'segment_size' number of characters // in the string. @@ -11240,38 +11218,42 @@ void DN_Docs_Demo() // of the string. { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 string = DN_Str8_Segment(tmem.arena, /*string*/ DN_STR8("123456789"), /*segment_size*/ 3, /*segment_char*/ ','); - DN_Assert(string == DN_STR8("123,456,789")); + DN_Str8 string = DN_Str8Segment(tmem.arena, /*string*/ DN_Str8Lit("123456789"), /*segment_size*/ 3, /*segment_char*/ ','); + DN_Assert(DN_Str8Eq(string, DN_Str8Lit("123,456,789"))); } - // NOTE: DN_Str8_Split //////////////////////////////////////////////////////////////////////// + // NOTE: DN_Str8Split { // Splits the string at each delimiter into substrings occuring prior and // after until the next delimiter. DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); { - DN_Slice splits = DN_Str8_SplitAlloc(/*arena*/ tmem.arena, - /*string*/ DN_STR8("192.168.8.1"), - /*delimiter*/ DN_STR8("."), + DN_Str8SplitResult splits = DN_Str8SplitArena(/*arena*/ tmem.arena, + /*string*/ DN_Str8Lit("192.168.8.1"), + /*delimiter*/ DN_Str8Lit("."), /*mode*/ DN_Str8SplitIncludeEmptyStrings_No); - DN_Assert(splits.size == 4); - DN_Assert(splits.data[0] == DN_STR8("192") && splits.data[1] == DN_STR8("168") && splits.data[2] == DN_STR8("8") && splits.data[3] == DN_STR8("1")); + DN_Assert(splits.count == 4); + DN_Assert(DN_Str8Eq(splits.data[0], DN_Str8Lit("192")) && + DN_Str8Eq(splits.data[1], DN_Str8Lit("168")) && + DN_Str8Eq(splits.data[2], DN_Str8Lit("8")) && + DN_Str8Eq(splits.data[3], DN_Str8Lit("1"))); } // You can include empty strings that occur when splitting by setting // the split mode to include empty strings. { - DN_Slice splits = DN_Str8_SplitAlloc(/*arena*/ tmem.arena, - /*string*/ DN_STR8("a--b"), - /*delimiter*/ DN_STR8("-"), + DN_Str8SplitResult splits = DN_Str8SplitArena(/*arena*/ tmem.arena, + /*string*/ DN_Str8Lit("a--b"), + /*delimiter*/ DN_Str8Lit("-"), /*mode*/ DN_Str8SplitIncludeEmptyStrings_Yes); - DN_Assert(splits.size == 3); - DN_Assert(splits.data[0] == DN_STR8("a") && splits.data[1] == DN_STR8("") && splits.data[2] == DN_STR8("b")); + DN_Assert(splits.count == 3); + DN_Assert(DN_Str8Eq(splits.data[0], DN_Str8Lit("a")) && + DN_Str8Eq(splits.data[1], DN_Str8Lit("")) && + DN_Str8Eq(splits.data[2], DN_Str8Lit("b"))); } } - // NOTE: DN_Str8_ToI64 //////////////////////////////////////////////////////////////////////// - // NOTE: DN_Str8_ToU64 //////////////////////////////////////////////////////////////////////// + // NOTE: DN_I64FromStr8, DN_U64FromStr8 // // Convert a number represented as a string to a signed 64 bit number. // @@ -11291,31 +11273,31 @@ void DN_Docs_Demo() // 'ToI64' either '+' or '-' prefix is permitted { { - DN_Str8ToI64Result result = DN_Str8_ToI64(DN_STR8("-1,234"), /*separator*/ ','); + DN_I64FromResult result = DN_I64FromStr8(DN_Str8Lit("-1,234"), /*separator*/ ','); DN_Assert(result.success && result.value == -1234); } { - DN_Str8ToI64Result result = DN_Str8_ToI64(DN_STR8("-1,234"), /*separator*/ 0); + DN_I64FromResult result = DN_I64FromStr8(DN_Str8Lit("-1,234"), /*separator*/ 0); DN_Assert(!result.success && result.value == 1); // 1 because it's a greedy conversion } } - // NOTE: DN_Str8_TrimByteOrderMark //////////////////////////////////////////////////////////// + // NOTE: DN_Str8TrimByteOrderMark // // Removes a leading UTF8, UTF16 BE/LE, UTF32 BE/LE byte order mark from the // string if it's present. - // NOTE: DN_STR_FMT /////////////////////////////////////////////////////////////////////////// + // NOTE: DN_Str8PrintFmt // // Unpacks a string struct that has the fields {.data, .size} for printing a // pointer and length style string using the printf format specifier "%.*s" // - // printf("%.*s\n", DN_STR_FMT(DN_STR8("Hello world"))); + // printf("%.*s\n", DN_Str8PrintFmt(DN_Str8Lit("Hello world"))); - // NOTE: DN_Str8Builder_AppendF //////////////////////////////////////////////////////////// - // NOTE: DN_Str8Builder_AppendFV //////////////////////////////////////////////////////////// - // NOTE: DN_Str8Builder_AppendRef //////////////////////////////////////////////////////////// - // NOTE: DN_Str8Builder_AppendCopy //////////////////////////////////////////////////////////// + // NOTE: DN_Str8BuilderAppendF + // NOTE: DN_Str8BuilderAppendFV + // NOTE: DN_Str8BuilderAppendRef + // NOTE: DN_Str8BuilderAppendCopy // // - Appends a string to the string builder as follows // @@ -11323,8 +11305,8 @@ void DN_Docs_Demo() // AppendCopy: Stores the string slice by copy (with builder's arena) // AppendF/V: Constructs a format string and calls 'AppendRef' - // NOTE: DN_Str8Builder_Build /////////////////////////////////////////////////////////// - // NOTE: DN_Str8Builder_BuildCRT /////////////////////////////////////////////////////////// + // NOTE: DN_Str8BuilderBuild + // NOTE: DN_Str8BuilderBuildCRT // // Constructs the final string by merging all the appended strings into // one merged string. @@ -11332,11 +11314,11 @@ void DN_Docs_Demo() // The CRT variant calls into 'malloc' and the string *must* be released // using 'free'. - // NOTE: DN_Str8Builder_BuildSlice /////////////////////////////////////////////////////////// + // NOTE: DN_Str8BuilderBuildSlice // // Constructs the final string into an array of strings (e.g. a slice) - // NOTE: DN_TicketMutex /////////////////////////////////////////////////////////////////////// + // NOTE: DN_TicketMutex // // A mutex implemented using an atomic compare and swap on tickets handed // out for each critical section. @@ -11356,13 +11338,13 @@ void DN_Docs_Demo() DN_TicketMutex_Begin(&mutex); // Simple procedural mutual exclusion lock DN_TicketMutex_End(&mutex); - // NOTE: DN_TicketMutex_MakeTicket //////////////////////////////////////////////////////// + // NOTE: DN_TicketMutex_MakeTicket // // Request the next available ticket for locking from the mutex. DN_UInt ticket = DN_TicketMutex_MakeTicket(&mutex); if (DN_TicketMutex_CanLock(&mutex, ticket)) { - // NOTE: DN_TicketMutex_BeginTicket /////////////////////////////////////////////////// + // NOTE: DN_TicketMutex_BeginTicket // // Locks the mutex using the given ticket if possible. If it's not // the next ticket to be locked the executing thread will block @@ -11373,7 +11355,7 @@ void DN_Docs_Demo() } } - // NOTE: DN_ThreadContext ///////////////////////////////////////////////////////////////////// + // NOTE: DN_ThreadContext // // Each thread is assigned in their thread-local storage (TLS) tmem and // permanent arena allocators. These can be used for allocations with a @@ -11423,21 +11405,21 @@ void DN_Docs_Demo() // @param[in] conflict_arena A pointer to the arena currently being used in the // function - // NOTE: DN_CVT_Str8FromU64 ///////////////////////////////////////////////////////////////////////// + // NOTE: DN_Str8x32FromFmt { - DN_CVTU64Str8 string = DN_CVT_Str8FromU64(123123, ','); - if (0) // Prints "123,123" - printf("%.*s", DN_STR_FMT(string)); + DN_Str8x32 string = DN_Str8x32FromFmt("%d", 123123); + if (0) // Prints "123123" + printf("%.*s", DN_Str8PrintFmt(string)); } - // NOTE: DN_CVT_AgeFromU64 ////////////////////////////////////////////////////////////////////////// + // NOTE: DN_CVT_AgeFromU64 { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 string = DN_CVT_AgeFromU64(tmem.arena, DN_HoursToSec(2) + DN_MinutesToSec(30), DN_CVTU64AgeUnit_All); - DN_Assert(DN_Str8_Eq(string, DN_STR8("2h 30m"))); + DN_Str8x128 string = DN_AgeStr8FromSecF64(DN_SecFromHours(2) + DN_SecFromMins(30), DN_AgeUnit_All); + DN_Assert(DN_Str8Eq(DN_Str8FromStruct(&string), DN_Str8Lit("2h 30m"))); } - // NOTE: DN_VArray //////////////////////////////////////////////////////////////////////////// + // NOTE: DN_VArray // // An array that is backed by virtual memory by reserving addressing space // and comitting pages as items are allocated in the array. This array never @@ -11461,8 +11443,8 @@ void DN_Docs_Demo() // In addition to no realloc on expansion or shrinking. // { - // NOTE: DN_VArray_Init /////////////////////////////////////////////////////////// - // NOTE: DN_VArray_InitByteSize /////////////////////////////////////////////////////////// + // NOTE: DN_VArray_Init + // NOTE: DN_VArray_InitByteSize // // Initialise an array with the requested byte size or item capacity // respectively. The returned array may have a higher capacity than the @@ -11472,10 +11454,10 @@ void DN_Docs_Demo() DN_VArray array = DN_VArray_Init(1024); DN_Assert(array.size == 0 && array.max >= 1024); - // NOTE: DN_VArray_Make ////////////////////////////////////////////////////////////// - // NOTE: DN_VArray_Add ////////////////////////////////////////////////////////////// - // NOTE: DN_VArray_MakeArray ////////////////////////////////////////////////////////////// - // NOTE: DN_VArray_AddArray ////////////////////////////////////////////////////////////// + // NOTE: DN_VArray_Make + // NOTE: DN_VArray_Add + // NOTE: DN_VArray_MakeArray + // NOTE: DN_VArray_AddArray // // Allocate items from the array where: // @@ -11487,7 +11469,7 @@ void DN_Docs_Demo() int *item = DN_VArray_Add(&array, 0xCAFE); DN_Assert(*item == 0xCAFE && array.size == 1); - // NOTE: DN_VArray_AddCArray ///////////////////////////////////////////////////////////// + // NOTE: DN_VArray_AddCArray DN_VArray_AddCArray(&array, {1, 2, 3}); DN_Assert(array.size == 4); @@ -11498,7 +11480,7 @@ void DN_Docs_Demo() if (index != 1) continue; - // NOTE: DN_VArray_EraseRange ///////////////////////////////////////////////////////// + // NOTE: DN_VArray_EraseRange // // Erase the next 'count' items at 'begin_index' in the array. // 'count' can be positive or negative which dictates the if we @@ -11533,7 +11515,7 @@ void DN_Docs_Demo() array.data[2] == 3); #endif - // NOTE: DN_VArray_Reserve //////////////////////////////////////////////////////////////////// + // NOTE: DN_VArray_Reserve // // Ensure that the requested number of items are backed by physical pages // from the OS. Calling this pre-emptively will minimise syscalls into the @@ -11546,31 +11528,31 @@ void DN_Docs_Demo() DN_VArray_Deinit(&array); } - // NOTE: DN_W32_LastError ///////////////////////////////////////////////////////////// - // NOTE: DN_W32_ErrorCodeToMsg ///////////////////////////////////////////////////////////// + // NOTE: DN_W32_LastError + // NOTE: DN_W32_ErrorCodeToMsg #if defined(DN_PLATFORM_WIN32) if (0) { // Generate the error string for the last Win32 API called that return // an error value. DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); DN_W32Error get_last_error = DN_W32_LastError(tmem.arena); - printf("Error (%lu): %.*s", get_last_error.code, DN_STR_FMT(get_last_error.msg)); + printf("Error (%lu): %.*s", get_last_error.code, DN_Str8PrintFmt(get_last_error.msg)); // Alternatively, pass in the error code directly DN_W32Error error_msg_for_code = DN_W32_ErrorCodeToMsg(tmem.arena, /*error_code*/ 0); - printf("Error (%lu): %.*s", error_msg_for_code.code, DN_STR_FMT(error_msg_for_code.msg)); + printf("Error (%lu): %.*s", error_msg_for_code.code, DN_Str8PrintFmt(error_msg_for_code.msg)); } - // NOTE: DN_W32_MakeProcessDPIAware /////////////////////////////////////////////////////////// + // NOTE: DN_W32_MakeProcessDPIAware // // Call once at application start-up to ensure that the application is DPI // aware on Windows and ensure that application UI is scaled up // appropriately for the monitor. - // NOTE: DN_W32_Str8ToStr16 ///////////////////////////////////////////////////////////// - // NOTE: DN_W32_Str8ToStr16Buffer ///////////////////////////////////////////////////////////// - // NOTE: DN_W32_Str16ToStr8 ///////////////////////////////////////////////////////////// - // NOTE: DN_W32_Str16ToStr8Buffer ///////////////////////////////////////////////////////////// + // NOTE: DN_W32_Str8ToStr16 + // NOTE: DN_W32_Str8ToStr16Buffer + // NOTE: DN_W32_Str16ToStr8 + // NOTE: DN_W32_Str16ToStr8Buffer // // Convert a UTF8 <-> UTF16 string. // @@ -13161,15 +13143,14 @@ DN_API DN_Str8x256 DN_M4_ColumnMajorString(DN_M4 mat) for (int row = 0; row < 4; row++) { for (int it = 0; it < 4; it++) { if (it == 0) - DN_IStr8_AppendF(&result, "|"); - DN_IStr8_AppendF(&result, "%.5f", mat.columns[it][row]); + DN_FmtAppend(result.data, &result.size, sizeof(result.data), "|"); + DN_FmtAppend(result.data, &result.size, sizeof(result.data), "%.5f", mat.columns[it][row]); if (it != 3) - DN_IStr8_AppendF(&result, ", "); + DN_FmtAppend(result.data, &result.size, sizeof(result.data), ", "); else - DN_IStr8_AppendF(&result, "|\n"); + DN_FmtAppend(result.data, &result.size, sizeof(result.data), "|\n"); } } - return result; } @@ -13605,8 +13586,8 @@ DN_API void DN_ASYNC_WaitTask (DN_OSSemaphore *sem, DN_U32 timeout_ms); static DN_I32 DN_ASYNC_ThreadEntryPoint_(DN_OSThread *thread) { - DN_OS_ThreadSetName(DN_Str8_FromIStr8(&thread->name)); - DN_ASYNCCore *async = DN_CAST(DN_ASYNCCore *) thread->user_context; + DN_OS_ThreadSetName(DN_Str8FromPtr(thread->name.data, thread->name.size)); + DN_ASYNCCore *async = DN_Cast(DN_ASYNCCore *) thread->user_context; DN_Ring *ring = &async->ring; for (;;) { DN_OS_SemaphoreWait(&async->worker_sem, UINT32_MAX); @@ -13650,7 +13631,7 @@ DN_API void DN_ASYNC_Init(DN_ASYNCCore *async, char *base, DN_USize base_size, D async->threads = threads; for (DN_ForIndexU(index, async->thread_count)) { DN_OSThread *thread = async->threads + index; - DN_IStr8_AppendF(&thread->name, "ASYNC W%zu", index); + DN_FmtAppend(thread->name.data, &thread->name.size, DN_ArrayCountU(thread->name.data), "ASYNC W%zu", index); DN_OS_ThreadInit(thread, DN_ASYNC_ThreadEntryPoint_, async); } } @@ -13728,11 +13709,11 @@ DN_API void DN_BinPack_U64(DN_BinPack *pack, DN_BinPackMode mode, DN_U64 *item) if (mode == DN_BinPackMode_Serialise) { DN_U64 it = *item; do { - DN_U8 write_value = DN_CAST(DN_U8)(it & VALUE_MASK); + DN_U8 write_value = DN_Cast(DN_U8)(it & VALUE_MASK); it >>= 7; if (it) write_value |= CONTINUE_BIT; - DN_Str8Builder_AppendBytesCopy(&pack->writer, &write_value, sizeof(write_value)); + DN_Str8BuilderAppendBytesCopy(&pack->writer, &write_value, sizeof(write_value)); } while (it); } else { *item = 0; @@ -13740,7 +13721,7 @@ DN_API void DN_BinPack_U64(DN_BinPack *pack, DN_BinPackMode mode, DN_U64 *item) for (DN_U8 src = CONTINUE_BIT; (src & CONTINUE_BIT) && bits_read < 64; bits_read += 7) { src = pack->read.data[pack->read_index++]; DN_U8 masked_src = src & VALUE_MASK; - *item |= (DN_CAST(DN_U64) masked_src << bits_read); + *item |= (DN_Cast(DN_U64) masked_src << bits_read); } } } @@ -13831,10 +13812,10 @@ DN_API void DN_BinPack_Str8FromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinPa { DN_BinPack_VarInt_(pack, mode, &string->size, sizeof(string->size)); if (mode == DN_BinPackMode_Serialise) { - DN_Str8Builder_AppendBytesCopy(&pack->writer, string->data, string->size); + DN_Str8BuilderAppendBytesCopy(&pack->writer, string->data, string->size); } else { - DN_Str8 src = DN_Str8_Slice(pack->read, pack->read_index, string->size); - *string = DN_Str8_FromStr8(arena, src); + DN_Str8 src = DN_Str8Slice(pack->read, pack->read_index, string->size); + *string = DN_Str8FromStr8Arena(arena, src); pack->read_index += src.size; } } @@ -13843,17 +13824,17 @@ DN_API void DN_BinPack_Str8FromPool(DN_BinPack *pack, DN_Pool *pool, DN_BinPackM { DN_BinPack_VarInt_(pack, mode, &string->size, sizeof(string->size)); if (mode == DN_BinPackMode_Serialise) { - DN_Str8Builder_AppendBytesCopy(&pack->writer, string->data, string->size); + DN_Str8BuilderAppendBytesCopy(&pack->writer, string->data, string->size); } else { - DN_Str8 src = DN_Str8_Slice(pack->read, pack->read_index, string->size); - *string = DN_Pool_AllocStr8Copy(pool, src); + DN_Str8 src = DN_Str8Slice(pack->read, pack->read_index, string->size); + *string = DN_Str8FromStr8Pool(pool, src); pack->read_index += src.size; } } DN_API void DN_BinPack_BytesFromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinPackMode mode, void **ptr, DN_USize *size) { - DN_Str8 string = DN_Str8_Init(*ptr, *size); + DN_Str8 string = DN_Str8FromPtr(*ptr, *size); DN_BinPack_Str8FromArena(pack, arena, mode, &string); *ptr = string.data; *size = string.size; @@ -13861,7 +13842,7 @@ DN_API void DN_BinPack_BytesFromArena(DN_BinPack *pack, DN_Arena *arena, DN_BinP DN_API void DN_BinPack_BytesFromPool(DN_BinPack *pack, DN_Pool *pool, DN_BinPackMode mode, void **ptr, DN_USize *size) { - DN_Str8 string = DN_Str8_Init(*ptr, *size); + DN_Str8 string = DN_Str8FromPtr(*ptr, *size); DN_BinPack_Str8FromPool(pack, pool, mode, &string); *ptr = string.data; *size = string.size; @@ -13871,9 +13852,9 @@ DN_API void DN_BinPack_CArray(DN_BinPack *pack, DN_BinPackMode mode, void *ptr, { DN_BinPack_VarInt_(pack, mode, &size, sizeof(size)); if (mode == DN_BinPackMode_Serialise) { - DN_Str8Builder_AppendBytesCopy(&pack->writer, ptr, size); + DN_Str8BuilderAppendBytesCopy(&pack->writer, ptr, size); } else { - DN_Str8 src = DN_Str8_Slice(pack->read, pack->read_index, size); + DN_Str8 src = DN_Str8Slice(pack->read, pack->read_index, size); DN_Assert(src.size == size); DN_Memcpy(ptr, src.data, DN_Min(src.size, size)); pack->read_index += src.size; @@ -13882,7 +13863,7 @@ DN_API void DN_BinPack_CArray(DN_BinPack *pack, DN_BinPackMode mode, void *ptr, DN_API DN_Str8 DN_BinPack_Build(DN_BinPack const *pack, DN_Arena *arena) { - DN_Str8 result = DN_Str8Builder_Build(&pack->writer, arena); + DN_Str8 result = DN_Str8BuilderBuild(&pack->writer, arena); return result; } // DN: Single header generator commented out this header => #include "dn_csv.h" @@ -13930,7 +13911,7 @@ static bool DN_CSV_TokeniserValid(DN_CSVTokeniser *tokeniser) static bool DN_CSV_TokeniserNextRow(DN_CSVTokeniser *tokeniser) { bool result = false; - if (DN_CSV_TokeniserValid(tokeniser) && DN_Str8_HasData(tokeniser->string)) { + if (DN_CSV_TokeniserValid(tokeniser) && tokeniser->string.size) { // NOTE: First time querying row iterator is nil, let tokeniser advance if (tokeniser->it) { // NOTE: Only advance the tokeniser if we're at the end of the line and @@ -13952,7 +13933,7 @@ static DN_Str8 DN_CSV_TokeniserNextField(DN_CSVTokeniser *tokeniser) if (!DN_CSV_TokeniserValid(tokeniser)) return result; - if (!DN_Str8_HasData(tokeniser->string)) { + if (tokeniser->string.size == 0) { tokeniser->bad = true; return result; } @@ -14024,8 +14005,8 @@ static DN_Str8 DN_CSV_TokeniserNextField(DN_CSVTokeniser *tokeniser) tokeniser->it++; // NOTE: Generate the record - result.data = DN_CAST(char *) begin; - result.size = DN_CAST(int)(end - begin); + result.data = DN_Cast(char *) begin; + result.size = DN_Cast(int)(end - begin); return result; } @@ -14059,7 +14040,7 @@ static int DN_CSV_TokeniserNextN(DN_CSVTokeniser *tokeniser, DN_Str8 *fields, in int result = 0; for (; result < fields_size; result++) { fields[result] = column_iterator ? DN_CSV_TokeniserNextColumn(tokeniser) : DN_CSV_TokeniserNextField(tokeniser); - if (!DN_CSV_TokeniserValid(tokeniser) || !DN_Str8_HasData(fields[result])) + if (!DN_CSV_TokeniserValid(tokeniser) || fields[result].size == 0) break; } @@ -14089,24 +14070,24 @@ static void DN_CSV_TokeniserSkipLineN(DN_CSVTokeniser *tokeniser, int count) static void DN_CSV_PackU64(DN_CSVPack *pack, DN_CSVSerialise serialise, DN_U64 *value) { if (serialise == DN_CSVSerialise_Read) { - DN_Str8 csv_value = DN_CSV_TokeniserNextColumn(&pack->read_tokeniser); - DN_Str8ToU64Result to_u64 = DN_Str8_ToU64(csv_value, 0); + DN_Str8 csv_value = DN_CSV_TokeniserNextColumn(&pack->read_tokeniser); + DN_U64FromResult to_u64 = DN_U64FromStr8(csv_value, 0); DN_Assert(to_u64.success); *value = to_u64.value; } else { - DN_Str8Builder_AppendF(&pack->write_builder, "%s%" PRIu64, pack->write_column++ ? "," : "", *value); + DN_Str8BuilderAppendF(&pack->write_builder, "%s%" PRIu64, pack->write_column++ ? "," : "", *value); } } static void DN_CSV_PackI64(DN_CSVPack *pack, DN_CSVSerialise serialise, DN_I64 *value) { if (serialise == DN_CSVSerialise_Read) { - DN_Str8 csv_value = DN_CSV_TokeniserNextColumn(&pack->read_tokeniser); - DN_Str8ToI64Result to_i64 = DN_Str8_ToI64(csv_value, 0); + DN_Str8 csv_value = DN_CSV_TokeniserNextColumn(&pack->read_tokeniser); + DN_I64FromResult to_i64 = DN_I64FromStr8(csv_value, 0); DN_Assert(to_i64.success); *value = to_i64.value; } else { - DN_Str8Builder_AppendF(&pack->write_builder, "%s%" PRIu64, pack->write_column++ ? "," : "", *value); + DN_Str8BuilderAppendF(&pack->write_builder, "%s%" PRIu64, pack->write_column++ ? "," : "", *value); } } @@ -14163,9 +14144,9 @@ static void DN_CSV_PackStr8(DN_CSVPack *pack, DN_CSVSerialise serialise, DN_Str8 { if (serialise == DN_CSVSerialise_Read) { DN_Str8 csv_value = DN_CSV_TokeniserNextColumn(&pack->read_tokeniser); - *str8 = DN_Str8_FromStr8(arena, csv_value); + *str8 = DN_Str8FromStr8Arena(arena, csv_value); } else { - DN_Str8Builder_AppendF(&pack->write_builder, "%s%.*s", pack->write_column++ ? "," : "", DN_STR_FMT(*str8)); + DN_Str8BuilderAppendF(&pack->write_builder, "%s%.*s", pack->write_column++ ? "," : "", DN_Str8PrintFmt(*str8)); } } @@ -14176,7 +14157,7 @@ static void DN_CSV_PackBuffer(DN_CSVPack *pack, DN_CSVSerialise serialise, void *size = DN_Min(*size, csv_value.size); DN_Memcpy(dest, csv_value.data, *size); } else { - DN_Str8Builder_AppendF(&pack->write_builder, "%s%.*s", pack->write_column++ ? "," : "", DN_CAST(int)(*size), dest); + DN_Str8BuilderAppendF(&pack->write_builder, "%s%.*s", pack->write_column++ ? "," : "", DN_Cast(int)(*size), dest); } } @@ -14194,7 +14175,7 @@ static bool DN_CSV_PackNewLine(DN_CSVPack *pack, DN_CSVSerialise serialise) result = DN_CSV_TokeniserNextRow(&pack->read_tokeniser); } else { pack->write_column = 0; - result = DN_Str8Builder_AppendRef(&pack->write_builder, DN_STR8("\n")); + result = DN_Str8BuilderAppendRef(&pack->write_builder, DN_Str8Lit("\n")); } return result; } @@ -14222,7 +14203,7 @@ DN_MSVC_WARNING_POP // 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) { - auto buffer = DN_CAST(uint8_t const *)bytes; + auto buffer = DN_Cast(uint8_t const *)bytes; for (DN_USize i = 0; i < size; i++) hash = (buffer[i] ^ hash) * 16777619 /*FNV Prime*/; return hash; @@ -14236,7 +14217,7 @@ DN_API uint32_t DN_FNV1A32_Hash(void const *bytes, DN_USize size) DN_API uint64_t DN_FNV1A64_Iterate(void const *bytes, DN_USize size, uint64_t hash) { - auto buffer = DN_CAST(uint8_t const *)bytes; + auto buffer = DN_Cast(uint8_t const *)bytes; for (DN_USize i = 0; i < size; i++) hash = (buffer[i] ^ hash) * 1099511628211 /*FNV Prime*/; return hash; @@ -14572,7 +14553,7 @@ 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_Str8 result = DN_Str8Builder_Build(&builder->string_builder, arena); + DN_Str8 result = DN_Str8BuilderBuild(&builder->string_builder, arena); return result; } @@ -14608,18 +14589,18 @@ DN_API void DN_JSONBuilder_KeyValue(DN_JSONBuilder *builder, DN_Str8 key, DN_Str int spaces = builder->indent_level * spaces_per_indent; if (key.size) - DN_Str8Builder_AppendF(&builder->string_builder, + DN_Str8BuilderAppendF(&builder->string_builder, "%.*s%*c\"%.*s\": %.*s", prefix_size, prefix, spaces, ' ', - DN_STR_FMT(key), - DN_STR_FMT(value)); + DN_Str8PrintFmt(key), + DN_Str8PrintFmt(value)); else if (spaces == 0) - DN_Str8Builder_AppendF(&builder->string_builder, "%.*s%.*s", prefix_size, prefix, DN_STR_FMT(value)); + DN_Str8BuilderAppendF(&builder->string_builder, "%.*s%.*s", prefix_size, prefix, DN_Str8PrintFmt(value)); else - DN_Str8Builder_AppendF(&builder->string_builder, "%.*s%*c%.*s", prefix_size, prefix, spaces, ' ', DN_STR_FMT(value)); + DN_Str8BuilderAppendF(&builder->string_builder, "%.*s%*c%.*s", prefix_size, prefix, spaces, ' ', DN_Str8PrintFmt(value)); if (item == DN_JSONBuilderItem_OpenContainer) builder->indent_level++; @@ -14630,7 +14611,7 @@ DN_API void DN_JSONBuilder_KeyValue(DN_JSONBuilder *builder, DN_Str8 key, DN_Str DN_API void DN_JSONBuilder_KeyValueFV(DN_JSONBuilder *builder, DN_Str8 key, char const *value_fmt, va_list args) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(builder->string_builder.arena); - DN_Str8 value = DN_Str8_FromFV(tmem.arena, value_fmt, args); + DN_Str8 value = DN_Str8FromFmtVArena(tmem.arena, value_fmt, args); DN_JSONBuilder_KeyValue(builder, key, value); } @@ -14644,22 +14625,22 @@ DN_API void DN_JSONBuilder_KeyValueF(DN_JSONBuilder *builder, DN_Str8 key, char DN_API void DN_JSONBuilder_ObjectBeginNamed(DN_JSONBuilder *builder, DN_Str8 name) { - DN_JSONBuilder_KeyValue(builder, name, DN_STR8("{")); + DN_JSONBuilder_KeyValue(builder, name, DN_Str8Lit("{")); } DN_API void DN_JSONBuilder_ObjectEnd(DN_JSONBuilder *builder) { - DN_JSONBuilder_KeyValue(builder, DN_STR8(""), DN_STR8("}")); + DN_JSONBuilder_KeyValue(builder, DN_Str8Lit(""), DN_Str8Lit("}")); } DN_API void DN_JSONBuilder_ArrayBeginNamed(DN_JSONBuilder *builder, DN_Str8 name) { - DN_JSONBuilder_KeyValue(builder, name, DN_STR8("[")); + DN_JSONBuilder_KeyValue(builder, name, DN_Str8Lit("[")); } DN_API void DN_JSONBuilder_ArrayEnd(DN_JSONBuilder *builder) { - DN_JSONBuilder_KeyValue(builder, DN_STR8(""), DN_STR8("]")); + DN_JSONBuilder_KeyValue(builder, DN_Str8Lit(""), DN_Str8Lit("]")); } DN_API void DN_JSONBuilder_Str8Named(DN_JSONBuilder *builder, DN_Str8 key, DN_Str8 value) @@ -14705,136 +14686,7 @@ DN_API void DN_JSONBuilder_F64Named(DN_JSONBuilder *builder, DN_Str8 key, double DN_API void DN_JSONBuilder_BoolNamed(DN_JSONBuilder *builder, DN_Str8 key, bool value) { - DN_Str8 value_string = value ? DN_STR8("true") : DN_STR8("false"); + DN_Str8 value_string = value ? DN_Str8Lit("true") : DN_Str8Lit("false"); DN_JSONBuilder_KeyValueF(builder, key, "%.*s", value_string.size, value_string.data); } -#endif // !defined(DN_NO_JSON_BUILDER) - -// NOTE: DN_JobQueue /////////////////////////////////////////////////////////////////////////////// -DN_API DN_JobQueueSPMC DN_OS_JobQueueSPMCInit() -{ - DN_JobQueueSPMC result = {}; - result.thread_wait_for_job_semaphore = DN_OS_SemaphoreInit(0 /*initial_count*/); - result.wait_for_completion_semaphore = DN_OS_SemaphoreInit(0 /*initial_count*/); - result.complete_queue_write_semaphore = DN_OS_SemaphoreInit(DN_ArrayCountU(result.complete_queue)); - result.mutex = DN_OS_MutexInit(); - return result; -} - -DN_API bool DN_OS_JobQueueSPMCCanAdd(DN_JobQueueSPMC const *queue, uint32_t count) -{ - uint32_t read_index = queue->read_index; - uint32_t write_index = queue->write_index; - uint32_t size = write_index - read_index; - bool result = (size + count) <= DN_ArrayCountU(queue->jobs); - return result; -} - -DN_API bool DN_OS_JobQueueSPMCAddArray(DN_JobQueueSPMC *queue, DN_Job *jobs, uint32_t count) -{ - if (!queue) - return false; - - uint32_t const pot_mask = DN_ArrayCountU(queue->jobs) - 1; - uint32_t read_index = queue->read_index; - uint32_t write_index = queue->write_index; - uint32_t size = write_index - read_index; - - if ((size + count) > DN_ArrayCountU(queue->jobs)) - return false; - - for (size_t offset = 0; offset < count; offset++) { - uint32_t wrapped_write_index = (write_index + offset) & pot_mask; - queue->jobs[wrapped_write_index] = jobs[offset]; - } - - DN_OS_MutexLock(&queue->mutex); - queue->write_index += count; - DN_OS_SemaphoreIncrement(&queue->thread_wait_for_job_semaphore, count); - DN_OS_MutexUnlock(&queue->mutex); - return true; -} - -DN_API bool DN_OS_JobQueueSPMCAdd(DN_JobQueueSPMC *queue, DN_Job job) -{ - bool result = DN_OS_JobQueueSPMCAddArray(queue, &job, 1); - return result; -} - -DN_API int32_t DN_OS_JobQueueSPMCThread(DN_OSThread *thread) -{ - DN_JobQueueSPMC *queue = DN_CAST(DN_JobQueueSPMC *) thread->user_context; - uint32_t const pot_mask = DN_ArrayCountU(queue->jobs) - 1; - static_assert(DN_ArrayCountU(queue->jobs) == DN_ArrayCountU(queue->complete_queue), "PoT mask is used to mask access to both arrays"); - - for (;;) { - DN_OS_SemaphoreWait(&queue->thread_wait_for_job_semaphore, DN_OS_SEMAPHORE_INFINITE_TIMEOUT); - if (queue->quit) - break; - - DN_Assert(queue->read_index != queue->write_index); - - DN_OS_MutexLock(&queue->mutex); - uint32_t wrapped_read_index = queue->read_index & pot_mask; - DN_Job job = queue->jobs[wrapped_read_index]; - queue->read_index += 1; - DN_OS_MutexUnlock(&queue->mutex); - - job.elapsed_tsc -= DN_CPUGetTSC(); - job.func(thread, job.user_context); - job.elapsed_tsc += DN_CPUGetTSC(); - - if (job.add_to_completion_queue) { - DN_OS_SemaphoreWait(&queue->complete_queue_write_semaphore, DN_OS_SEMAPHORE_INFINITE_TIMEOUT); - DN_OS_MutexLock(&queue->mutex); - queue->complete_queue[(queue->complete_write_index++ & pot_mask)] = job; - DN_OS_MutexUnlock(&queue->mutex); - DN_OS_SemaphoreIncrement(&queue->complete_queue_write_semaphore, 1); - } - - // NOTE: Update finish counter - DN_OS_MutexLock(&queue->mutex); - queue->finish_index += 1; - - // NOTE: If all jobs are finished and we have another thread who is - // blocked via `WaitForCompletion` for this job queue, we will go - // release the semaphore to wake them all up. - bool all_jobs_finished = queue->finish_index == queue->write_index; - if (all_jobs_finished && queue->threads_waiting_for_completion) { - DN_OS_SemaphoreIncrement(&queue->wait_for_completion_semaphore, - queue->threads_waiting_for_completion); - queue->threads_waiting_for_completion = 0; - } - DN_OS_MutexUnlock(&queue->mutex); - } - - return queue->quit_exit_code; -} - -DN_API void DN_OS_JobQueueSPMCWaitForCompletion(DN_JobQueueSPMC *queue) -{ - DN_OS_MutexLock(&queue->mutex); - if (queue->finish_index == queue->write_index) { - DN_OS_MutexUnlock(&queue->mutex); - return; - } - queue->threads_waiting_for_completion++; - DN_OS_MutexUnlock(&queue->mutex); - - DN_OS_SemaphoreWait(&queue->wait_for_completion_semaphore, DN_OS_SEMAPHORE_INFINITE_TIMEOUT); -} - -DN_API DN_USize DN_OS_JobQueueSPMCGetFinishedJobs(DN_JobQueueSPMC *queue, DN_Job *jobs, DN_USize jobs_size) -{ - DN_USize result = 0; - if (!queue || !jobs || jobs_size <= 0) - return result; - - uint32_t const pot_mask = DN_ArrayCountU(queue->jobs) - 1; - DN_OS_MutexLock(&queue->mutex); - while (queue->complete_read_index < queue->complete_write_index && result < jobs_size) - jobs[result++] = queue->complete_queue[(queue->complete_read_index++ & pot_mask)]; - DN_OS_MutexUnlock(&queue->mutex); - - return result; -} \ No newline at end of file +#endif // !defined(DN_NO_JSON_BUILDER) \ No newline at end of file diff --git a/Single_Header/dn_single_header.h b/Single_Header/dn_single_header.h index 053e9ae..aaae81e 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-10-11 17:43:41 +// Generated by the DN single header generator 2025-11-04 23:31:23 #if !defined(DN_BASE_INC_H) #define DN_BASE_INC_H @@ -187,7 +187,7 @@ #endif // NOTE: Type Cast ///////////////////////////////////////////////////////////////////////////////// -#define DN_CAST(val) (val) +#define DN_Cast(val) (val) // NOTE: Zero initialisation macro ///////////////////////////////////////////////////////////////// #if defined(__cplusplus) @@ -236,11 +236,13 @@ #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_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_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_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)) @@ -301,7 +303,7 @@ } while (0) // NOTE: Size -#define DN_SizeOfI(val) DN_CAST(ptrdiff_t)sizeof(val) +#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) @@ -313,12 +315,12 @@ #define DN_Gigabytes(val) ((DN_U64)1024 * DN_Megabytes(val)) // NOTE: Time -#define DN_SecondsToMs(val) ((val) * 1000) -#define DN_MinutesToSec(val) ((val) * 60ULL) -#define DN_HoursToSec(val) (DN_MinutesToSec(val) * 60ULL) -#define DN_DaysToSec(val) (DN_HoursToSec(val) * 24ULL) -#define DN_WeeksToSec(val) (DN_DaysToSec(val) * 7ULL) -#define DN_YearsToSec(val) (DN_WeeksToSec(val) * 52ULL) +#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) @@ -379,10 +381,10 @@ typedef DN_I32 DN_B32; #define DN_ISIZE_MAX INTPTR_MAX #define DN_ISIZE_MIN INTPTR_MIN -enum DN_ZeroMem +enum DN_ZMem { - DN_ZeroMem_No, // Memory can be handed out without zero-ing it out - DN_ZeroMem_Yes, // Memory should be zero-ed out before giving to the callee + 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 @@ -391,21 +393,36 @@ struct DN_Str8 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_U8x32 -{ - DN_U8 data[32]; -}; - -struct DN_U8x64 -{ - DN_U8 data[64]; -}; +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 @@ -426,7 +443,7 @@ struct DN_CallSite DN_U32 line; }; -#define DN_CALL_SITE DN_CallSite { DN_STR8(__FILE__), DN_STR8(__func__), __LINE__ } +#define DN_CALL_SITE DN_CallSite { DN_Str8Lit(__FILE__), DN_Str8Lit(__func__), __LINE__ } // NOTE: Defer Macro #if defined(__cplusplus) @@ -465,7 +482,7 @@ struct DN_DeferHelper #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_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) @@ -622,228 +639,18 @@ struct DN_TicketMutex unsigned int volatile serving; // The ticket ID to block the mutex on until it is returned }; -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); - -#endif // !defined(DN_BASE_H) -// DN: Single header generator inlined this file => #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 +struct DN_U64FromResult { - DN_U64 address; - DN_U64 line_number; - DN_Str8 file_name; - DN_Str8 function_name; + bool success; + DN_U64 value; }; -struct DN_StackTraceRawFrame +struct DN_I64FromResult { - void *process; - DN_U64 base_addr; + bool success; + DN_I64 value; }; -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_StackTrace_WalkStr8FromHeap(...) DN_STR8("N/A") -#define DN_StackTrace_Walk(...) -#define DN_StackTrace_WalkResultIterate(...) -#define DN_StackTrace_WalkResultToStr8(...) DN_STR8("N/A") -#define DN_StackTrace_WalkStr8(...) DN_STR8("N/A") -#define DN_StackTrace_WalkStr8FromHeap(...) DN_STR8("N/A") -#define DN_StackTrace_GetFrames(...) -#define DN_StackTrace_RawFrameToFrame(...) -#define DN_StackTrace_Print(...) -#define DN_StackTrace_ReloadSymbols(...) -#else -DN_API DN_StackTraceWalkResult DN_StackTrace_Walk (struct DN_Arena *arena, DN_U16 limit); -DN_API bool DN_StackTrace_WalkResultIterate(DN_StackTraceWalkResultIterator *it, DN_StackTraceWalkResult const *walk); -DN_API DN_Str8 DN_StackTrace_WalkResultToStr8 (struct DN_Arena *arena, DN_StackTraceWalkResult const *walk, DN_U16 skip); -DN_API DN_Str8 DN_StackTrace_WalkStr8 (struct DN_Arena *arena, DN_U16 limit, DN_U16 skip); -DN_API DN_Str8 DN_StackTrace_WalkStr8FromHeap (DN_U16 limit, DN_U16 skip); -DN_API DN_Slice DN_StackTrace_GetFrames (struct DN_Arena *arena, DN_U16 limit); -DN_API DN_StackTraceFrame DN_StackTrace_RawFrameToFrame (struct DN_Arena *arena, DN_StackTraceRawFrame raw_frame); -DN_API void DN_StackTrace_Print (DN_U16 limit); -DN_API void DN_StackTrace_ReloadSymbols (); -#endif -#endif // !defined(DN_BASE_OS_H) -// DN: Single header generator inlined this file => #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_StackTrace_WalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \ - DN_LOG_ErrorF("Hard assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ - DN_STR_FMT(stack_trace_), \ - ##__VA_ARGS__); \ - DN_DebugBreak; \ - } \ - } while (0) -#define DN_HardAssert(expr) DN_HardAssertF(expr, "") - -#if defined(DN_NO_ASSERT) - #define DN_Assert(...) - #define DN_AssertOnce(...) - #define DN_AssertF(...) - #define DN_AssertFOnce(...) -#else - #define DN_AssertF(expr, fmt, ...) \ - do { \ - if (!(expr)) { \ - DN_Str8 stack_trace_ = DN_StackTrace_WalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \ - DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ - DN_STR_FMT(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_StackTrace_WalkStr8FromHeap(128 /*limit*/, 2 /*skip*/); \ - DN_LOG_ErrorF("Assertion [" #expr "], stack trace was:\n\n%.*s\n\n" fmt, \ - DN_STR_FMT(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_StackTrace_Print(128 /*limit*/), DN_DebugBreak, false)) -#endif - -#endif -// DN: Single header generator inlined this file => #include "Base/dn_base_mem.h" -#if !defined(DN_BASE_MEM_H) -#define DN_BASE_MEM_H - -// DN: Single header generator commented out this header => #include "../dn_base_inc.h" - enum DN_MemCommit { DN_MemCommit_No, @@ -915,8 +722,7 @@ struct DN_ArenaBlock DN_U64 reserve_sum; }; -typedef uint32_t DN_ArenaFlags; - +typedef DN_U32 DN_ArenaFlags; enum DN_ArenaFlags_ { DN_ArenaFlags_Nil = 0, @@ -994,7 +800,7 @@ struct DN_ArenaTempMemScope 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 + #define DN_POOL_DEFAULT_ALIGN 16 #endif struct DN_PoolSlot @@ -1046,123 +852,129 @@ struct DN_Pool DN_U8 align; }; -DN_API DN_Arena DN_Arena_FromBuffer (void *buffer, DN_USize size, DN_ArenaFlags flags); -DN_API DN_Arena DN_Arena_FromMemFuncs (DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags, DN_ArenaMemFuncs mem_funcs); -DN_API void DN_Arena_Deinit (DN_Arena *arena); -DN_API bool DN_Arena_Commit (DN_Arena *arena, DN_U64 size); -DN_API bool DN_Arena_CommitTo (DN_Arena *arena, DN_U64 pos); -DN_API bool DN_Arena_Grow (DN_Arena *arena, DN_U64 reserve, DN_U64 commit); -DN_API void * DN_Arena_Alloc (DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZeroMem zero_mem); -DN_API void * DN_Arena_AllocContiguous (DN_Arena *arena, DN_U64 size, uint8_t align, DN_ZeroMem zero_mem); -DN_API void * DN_Arena_Copy (DN_Arena *arena, void const *data, DN_U64 size, uint8_t align); -DN_API void DN_Arena_PopTo (DN_Arena *arena, DN_U64 init_used); -DN_API void DN_Arena_Pop (DN_Arena *arena, DN_U64 amount); -DN_API DN_U64 DN_Arena_Pos (DN_Arena const *arena); -DN_API void DN_Arena_Clear (DN_Arena *arena); -DN_API bool DN_Arena_OwnsPtr (DN_Arena const *arena, void *ptr); -DN_API DN_ArenaStats DN_Arena_SumStatsArray (DN_ArenaStats const *array, DN_USize size); -DN_API DN_ArenaStats DN_Arena_SumStats (DN_ArenaStats lhs, DN_ArenaStats rhs); -DN_API DN_ArenaStats DN_Arena_SumArenaArrayToStats (DN_Arena const *array, DN_USize size); -DN_API DN_ArenaTempMem DN_Arena_TempMemBegin (DN_Arena *arena); -DN_API void DN_Arena_TempMemEnd (DN_ArenaTempMem mem); -#define DN_Arena_New_Frame(T, zero_mem) (T *)DN_Arena_Alloc(DN_OS_TLSGet()->frame_arena, sizeof(T), alignof(T), zero_mem) -#define DN_Arena_New(arena, T, zero_mem) (T *)DN_Arena_Alloc(arena, sizeof(T), alignof(T), zero_mem) -#define DN_Arena_NewArray(arena, T, count, zero_mem) (T *)DN_Arena_Alloc(arena, sizeof(T) * (count), alignof(T), zero_mem) -#define DN_Arena_NewCopy(arena, T, src) (T *)DN_Arena_Copy (arena, (src), sizeof(T), alignof(T)) -#define DN_Arena_NewArrayCopy(arena, T, src, count) (T *)DN_Arena_Copy (arena, (src), sizeof(T) * (count), alignof(T)) - -DN_API DN_Pool DN_Pool_FromArena (DN_Arena *arena, DN_U8 align); -DN_API bool DN_Pool_IsValid (DN_Pool const *pool); -DN_API void * DN_Pool_Alloc (DN_Pool *pool, DN_USize size); -DN_API DN_Str8 DN_Pool_AllocStr8FV (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, va_list args); -DN_API DN_Str8 DN_Pool_AllocStr8F (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...); -DN_API DN_Str8 DN_Pool_AllocStr8Copy (DN_Pool *pool, DN_Str8 string); -DN_API void DN_Pool_Dealloc (DN_Pool *pool, void *ptr); -DN_API void * DN_Pool_Copy (DN_Pool *pool, void const *data, DN_U64 size, uint8_t align); - -#define DN_Pool_New(pool, T) (T *)DN_Pool_Alloc(pool, sizeof(T)) -#define DN_Pool_NewArray(pool, T, count) (T *)DN_Pool_Alloc(pool, count * sizeof(T)) -#define DN_Pool_NewCopy(arena, T, src) (T *)DN_Pool_Copy (arena, (src), sizeof(T), alignof(T)) -#define DN_Pool_NewArrayCopy(arena, T, src, count) (T *)DN_Pool_Copy (arena, (src), sizeof(T) * (count), alignof(T)) -#endif // !defined(DN_BASE_MEM_H) -// DN: Single header generator inlined this file => #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 +struct DN_NibbleFromU8Result { - DN_LOGType_Debug, - DN_LOGType_Info, - DN_LOGType_Warning, - DN_LOGType_Error, - DN_LOGType_Count, + char nibble0; + char nibble1; }; -enum DN_LOGBold +enum DN_Str8EqCase { - DN_LOGBold_No, - DN_LOGBold_Yes, + DN_Str8EqCase_Sensitive, + DN_Str8EqCase_Insensitive, }; -struct DN_LOGStyle +enum DN_Str8IsAllType { - DN_LOGBold bold; - bool colour; - DN_U8 r, g, b; + DN_Str8IsAllType_Digits, + DN_Str8IsAllType_Hex, }; -struct DN_LOGTypeParam +struct DN_Str8BSplitResult { - bool is_u32_enum; - DN_U32 u32; + 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; }; -enum DN_LOGColourType +struct DN_Str8SplitResult { - DN_LOGColourType_Fg, - DN_LOGColourType_Bg, + DN_Str8 *data; + DN_USize count; }; -struct DN_LOGDate +struct DN_Str8Link { - DN_U16 year; - DN_U8 month; - DN_U8 day; - - DN_U8 hour; - DN_U8 minute; - DN_U8 second; + 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_LOGPrefixSize +struct DN_Str8Builder { - DN_USize size; - DN_USize padding; + 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 }; -typedef void DN_LOGEmitFromTypeFVFunc(DN_LOGTypeParam type, void *user_data, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, va_list args); +enum DN_Str8BuilderAdd +{ + DN_Str8BuilderAdd_Append, + DN_Str8BuilderAdd_Prepend, +}; -#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 inlined this file => #include "Base/dn_base_string.h" -#if !defined(DN_BASE_STRING_H) -#define DN_BASE_STRING_H +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, +}; -// DN: Single header generator commented out this header => #include "../dn_base_inc.h" +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; +}; #if !defined(DN_STB_SPRINTF_HEADER_ONLY) #define STB_SPRINTF_IMPLEMENTATION @@ -3105,232 +2917,495 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. DN_GCC_WARNING_POP DN_MSVC_WARNING_POP -#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__) +#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__) -struct DN_Str8Link +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_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_Str8FromStr8Arena (DN_Arena *pool, 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_Str8x64 DN_Str8x64FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x128 DN_Str8x128FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +DN_API DN_Str8x256 DN_Str8x256FromFmt (DN_FMT_ATTRIB char const *fmt, ...); +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) + +#endif // !defined(DN_BASE_H) +// DN: Single header generator inlined this file => #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_Str8 string; // The string - DN_Str8Link *next; // The next string in the linked list - DN_Str8Link *prev; // The prev string in the linked list + DN_U64 address; + DN_U64 line_number; + DN_Str8 file_name; + DN_Str8 function_name; }; -struct DN_Str8BSplitResult +struct DN_StackTraceRawFrame { - DN_Str8 lhs; - DN_Str8 rhs; + void *process; + DN_U64 base_addr; }; -struct DN_Str8FindResult +struct DN_StackTraceWalkResult { - 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 + 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 }; -enum DN_Str8IsAll +struct DN_StackTraceWalkResultIterator { - DN_Str8IsAll_Digits, - DN_Str8IsAll_Hex, + DN_StackTraceRawFrame raw_frame; + DN_U16 index; }; -enum DN_Str8EqCase + +#if defined(DN_FREESTANDING) +#define DN_StackTrace_WalkStr8FromHeap(...) DN_Str8Lit("N/A") +#define DN_StackTrace_Walk(...) +#define DN_StackTrace_WalkResultIterate(...) +#define DN_StackTrace_WalkResultToStr8(...) DN_Str8Lit("N/A") +#define DN_StackTrace_WalkStr8(...) DN_Str8Lit("N/A") +#define DN_StackTrace_WalkStr8FromHeap(...) DN_Str8Lit("N/A") +#define DN_StackTrace_GetFrames(...) +#define DN_StackTrace_RawFrameToFrame(...) +#define DN_StackTrace_Print(...) +#define DN_StackTrace_ReloadSymbols(...) +#else +DN_API DN_StackTraceWalkResult DN_StackTrace_Walk (struct DN_Arena *arena, DN_U16 limit); +DN_API bool DN_StackTrace_WalkResultIterate(DN_StackTraceWalkResultIterator *it, DN_StackTraceWalkResult const *walk); +DN_API DN_Str8 DN_StackTrace_WalkResultToStr8 (struct DN_Arena *arena, DN_StackTraceWalkResult const *walk, DN_U16 skip); +DN_API DN_Str8 DN_StackTrace_WalkStr8 (struct DN_Arena *arena, DN_U16 limit, DN_U16 skip); +DN_API DN_Str8 DN_StackTrace_WalkStr8FromHeap (DN_U16 limit, DN_U16 skip); +DN_API DN_Slice DN_StackTrace_GetFrames (struct DN_Arena *arena, DN_U16 limit); +DN_API DN_StackTraceFrame DN_StackTrace_RawFrameToFrame (struct DN_Arena *arena, DN_StackTraceRawFrame raw_frame); +DN_API void DN_StackTrace_Print (DN_U16 limit); +DN_API void DN_StackTrace_ReloadSymbols (); +#endif +#endif // !defined(DN_BASE_OS_H) +// DN: Single header generator inlined this file => #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_StackTrace_WalkStr8FromHeap(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, "") + +#if defined(DN_NO_ASSERT) + #define DN_Assert(...) + #define DN_AssertOnce(...) + #define DN_AssertF(...) + #define DN_AssertFOnce(...) +#else + #define DN_AssertF(expr, fmt, ...) \ + do { \ + if (!(expr)) { \ + DN_Str8 stack_trace_ = DN_StackTrace_WalkStr8FromHeap(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_StackTrace_WalkStr8FromHeap(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_StackTrace_Print(128 /*limit*/), DN_DebugBreak, false)) +#endif + +#endif +// DN: Single header generator inlined this file => #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_Str8EqCase_Sensitive, - DN_Str8EqCase_Insensitive, + DN_LOGType_Debug, + DN_LOGType_Info, + DN_LOGType_Warning, + DN_LOGType_Error, + DN_LOGType_Count, }; -enum DN_Str8FindFlag +enum DN_LOGBold { - 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, + DN_LOGBold_No, + DN_LOGBold_Yes, }; -enum DN_Str8SplitIncludeEmptyStrings +struct DN_LOGStyle { - DN_Str8SplitIncludeEmptyStrings_No, - DN_Str8SplitIncludeEmptyStrings_Yes, + DN_LOGBold bold; + bool colour; + DN_U8 r, g, b; }; -struct DN_Str8ToU64Result +struct DN_LOGTypeParam { - bool success; - uint64_t value; -}; - -struct DN_Str8ToI64Result -{ - bool success; - int64_t value; -}; - -struct DN_Str8DotTruncateResult -{ - bool truncated; + bool is_u32_enum; + DN_U32 u32; DN_Str8 str8; }; -struct DN_Str8Builder +enum DN_LOGColourType { - 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 + DN_LOGColourType_Fg, + DN_LOGColourType_Bg, }; -enum DN_Str8BuilderAdd +struct DN_LOGDate { - DN_Str8BuilderAdd_Append, - DN_Str8BuilderAdd_Prepend, + DN_U16 year; + DN_U8 month; + DN_U8 day; + + DN_U8 hour; + DN_U8 minute; + DN_U8 second; }; -struct DN_Str8x64 +struct DN_LOGPrefixSize { - char data[64]; DN_USize size; + DN_USize padding; }; -struct DN_Str8x256 -{ - char data[256]; - DN_USize size; -}; +typedef void DN_LOGEmitFromTypeFVFunc(DN_LOGTypeParam type, void *user_data, DN_CallSite call_site, DN_FMT_ATTRIB char const *fmt, va_list args); -DN_API DN_USize DN_CStr8_FSize (DN_FMT_ATTRIB char const *fmt, ...); -DN_API DN_USize DN_CStr8_FVSize (DN_FMT_ATTRIB char const *fmt, va_list args); -DN_API DN_USize DN_CStr8_Size (char const *a); -DN_API DN_USize DN_CStr16_Size (wchar_t const *a); - -#define DN_STR16(string) DN_Str16{(wchar_t *)(string), sizeof(string)/sizeof(string[0]) - 1} -#define DN_Str16_HasData(string) ((string).data && (string).size) - -#if defined(__cplusplus) -DN_API bool operator== (DN_Str16 const &lhs, DN_Str16 const &rhs); -DN_API bool operator!= (DN_Str16 const &lhs, DN_Str16 const &rhs); -#endif - -#define DN_STR8(string) DN_Str8{(char *)(string), (sizeof(string) - 1)} -#define DN_STR_FMT(string) (int)((string).size), (string).data -#define DN_Str8_Init(data, size) DN_Str8{(char *)(data), (size_t)(size)} -#define DN_Str8_HasData(string) ((string).data && (string).size) -DN_API DN_Str8 DN_Str8_Alloc (DN_Arena *arena, DN_USize size, DN_ZeroMem zero_mem); -DN_API DN_Str8 DN_Str8_FromCStr8 (char const *src); -DN_API DN_Str8 DN_Str8_FromF (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, ...); -DN_API DN_Str8 DN_Str8_FromFV (DN_Arena *arena, DN_FMT_ATTRIB char const *fmt, va_list args); -DN_API DN_Str8 DN_Str8_FromFPool (DN_Pool *pool, DN_FMT_ATTRIB char const *fmt, ...); -DN_API DN_Str8 DN_Str8_FromStr8 (DN_Arena *arena, DN_Str8 string); -DN_API bool DN_Str8_IsAll (DN_Str8 string, DN_Str8IsAll is_all); -DN_API char * DN_Str8_End (DN_Str8 string); -DN_API DN_Str8 DN_Str8_Slice (DN_Str8 string, DN_USize offset, DN_USize size); -DN_API DN_Str8 DN_Str8_Advance (DN_Str8 string, DN_USize amount); -DN_API DN_Str8 DN_Str8_NextLine (DN_Str8 string); -DN_API DN_Str8BSplitResult DN_Str8_BSplitArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size); -DN_API DN_Str8BSplitResult DN_Str8_BSplit (DN_Str8 string, DN_Str8 find); -DN_API DN_Str8BSplitResult DN_Str8_BSplitLastArray (DN_Str8 string, DN_Str8 const *find, DN_USize find_size); -DN_API DN_Str8BSplitResult DN_Str8_BSplitLast (DN_Str8 string, DN_Str8 find); -DN_API DN_USize DN_Str8_Split (DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_USize splits_count, DN_Str8SplitIncludeEmptyStrings mode); -DN_API DN_Slice DN_Str8_SplitAlloc (DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode); -DN_API DN_Str8FindResult DN_Str8_FindStr8Array (DN_Str8 string, DN_Str8 const *find, DN_USize find_size, DN_Str8EqCase eq_case); -DN_API DN_Str8FindResult DN_Str8_FindStr8 (DN_Str8 string, DN_Str8 find, DN_Str8EqCase eq_case); -DN_API DN_Str8FindResult DN_Str8_Find (DN_Str8 string, uint32_t flags); -DN_API DN_Str8 DN_Str8_Segment (DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char); -DN_API DN_Str8 DN_Str8_ReverseSegment (DN_Arena *arena, DN_Str8 src, DN_USize segment_size, char segment_char); -DN_API bool DN_Str8_Eq (DN_Str8 lhs, DN_Str8 rhs, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive); -DN_API bool DN_Str8_EqInsensitive (DN_Str8 lhs, DN_Str8 rhs); -DN_API bool DN_Str8_StartsWith (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive); -DN_API bool DN_Str8_StartsWithInsensitive (DN_Str8 string, DN_Str8 prefix); -DN_API bool DN_Str8_EndsWith (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive); -DN_API bool DN_Str8_EndsWithInsensitive (DN_Str8 string, DN_Str8 prefix); -DN_API bool DN_Str8_HasChar (DN_Str8 string, char ch); -DN_API DN_Str8 DN_Str8_TrimPrefix (DN_Str8 string, DN_Str8 prefix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive); -DN_API DN_Str8 DN_Str8_TrimHexPrefix (DN_Str8 string); -DN_API DN_Str8 DN_Str8_TrimSuffix (DN_Str8 string, DN_Str8 suffix, DN_Str8EqCase eq_case = DN_Str8EqCase_Sensitive); -DN_API DN_Str8 DN_Str8_TrimAround (DN_Str8 string, DN_Str8 trim_string); -DN_API DN_Str8 DN_Str8_TrimHeadWhitespace (DN_Str8 string); -DN_API DN_Str8 DN_Str8_TrimTailWhitespace (DN_Str8 string); -DN_API DN_Str8 DN_Str8_TrimWhitespaceAround (DN_Str8 string); -DN_API DN_Str8 DN_Str8_TrimByteOrderMark (DN_Str8 string); -DN_API DN_Str8 DN_Str8_FileNameFromPath (DN_Str8 path); -DN_API DN_Str8 DN_Str8_FileNameNoExtension (DN_Str8 path); -DN_API DN_Str8 DN_Str8_FilePathNoExtension (DN_Str8 path); -DN_API DN_Str8 DN_Str8_FileExtension (DN_Str8 path); -DN_API DN_Str8 DN_Str8_FileDirectoryFromPath (DN_Str8 path); -DN_API DN_Str8ToU64Result DN_Str8_ToU64 (DN_Str8 string, char separator); -DN_API DN_Str8ToI64Result DN_Str8_ToI64 (DN_Str8 string, char separator); -DN_API DN_Str8 DN_Str8_AppendF (DN_Arena *arena, DN_Str8 string, char const *fmt, ...); -DN_API DN_Str8 DN_Str8_AppendFV (DN_Arena *arena, DN_Str8 string, char const *fmt, va_list args); -DN_API DN_Str8 DN_Str8_FillF (DN_Arena *arena, DN_USize count, char const *fmt, ...); -DN_API DN_Str8 DN_Str8_FillFV (DN_Arena *arena, DN_USize count, char const *fmt, va_list args); -DN_API void DN_Str8_Remove (DN_Str8 *string, DN_USize offset, DN_USize size); -DN_API DN_Str8DotTruncateResult DN_Str8_DotTruncateMiddle (DN_Arena *arena, DN_Str8 str8, uint32_t side_size, DN_Str8 truncator); -DN_API DN_Str8 DN_Str8_Lower (DN_Arena *arena, DN_Str8 string); -DN_API DN_Str8 DN_Str8_Upper (DN_Arena *arena, DN_Str8 string); -#if defined(__cplusplus) -DN_API bool operator== (DN_Str8 const &lhs, DN_Str8 const &rhs); -DN_API bool operator!= (DN_Str8 const &lhs, DN_Str8 const &rhs); -#endif - -DN_API DN_Str8 DN_LStr8_AppendFV (char *buf, DN_USize *buf_size, DN_USize buf_max, char const *fmt, va_list args); -DN_API DN_Str8 DN_LStr8_AppendF (char *buf, DN_USize *buf_size, DN_USize buf_max, char const *fmt, ...); -#define DN_IStr8_AppendF(struct_ptr, fmt, ...) DN_LStr8_AppendF((struct_ptr)->data, &(struct_ptr)->size, DN_ArrayCountU((struct_ptr)->data), fmt, ##__VA_ARGS__) -#define DN_Str8_FromIStr8(struct_ptr) DN_Str8_Init((struct_ptr)->data, (struct_ptr)->size) - - -DN_API DN_Str8Builder DN_Str8Builder_FromArena (DN_Arena *arena); -DN_API DN_Str8Builder DN_Str8Builder_FromStr8PtrRef (DN_Arena *arena, DN_Str8 const *strings, DN_USize size); -DN_API DN_Str8Builder DN_Str8Builder_FromStr8PtrCopy (DN_Arena *arena, DN_Str8 const *strings, DN_USize size); -DN_API DN_Str8Builder DN_Str8Builder_FromBuilder (DN_Arena *arena, DN_Str8Builder const *builder); -DN_API bool DN_Str8Builder_AddArrayRef (DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize size, DN_Str8BuilderAdd add); -DN_API bool DN_Str8Builder_AddArrayCopy (DN_Str8Builder *builder, DN_Str8 const *strings, DN_USize size, DN_Str8BuilderAdd add); -DN_API bool DN_Str8Builder_AddFV (DN_Str8Builder *builder, DN_Str8BuilderAdd add, DN_FMT_ATTRIB char const *fmt, va_list args); -#define DN_Str8Builder_AppendArrayRef(builder, strings, size) DN_Str8Builder_AddArrayRef(builder, strings, size, DN_Str8BuilderAdd_Append) -#define DN_Str8Builder_AppendArrayCopy(builder, strings, size) DN_Str8Builder_AddArrayCopy(builder, strings, size, DN_Str8BuilderAdd_Append) -#define DN_Str8Builder_AppendSliceRef(builder, slice) DN_Str8Builder_AddArrayRef(builder, slice.data, slice.size, DN_Str8BuilderAdd_Append) -#define DN_Str8Builder_AppendSliceCopy(builder, slice) DN_Str8Builder_AddArrayCopy(builder, slice.data, slice.size, DN_Str8BuilderAdd_Append) -DN_API bool DN_Str8Builder_AppendRef (DN_Str8Builder *builder, DN_Str8 string); -DN_API bool DN_Str8Builder_AppendCopy (DN_Str8Builder *builder, DN_Str8 string); -#define DN_Str8Builder_AppendFV(builder, fmt, args) DN_Str8Builder_AddFV(builder, DN_Str8BuilderAdd_Append, fmt, args) -DN_API bool DN_Str8Builder_AppendF (DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...); -DN_API bool DN_Str8Builder_AppendBytesRef (DN_Str8Builder *builder, void const *ptr, DN_USize size); -DN_API bool DN_Str8Builder_AppendBytesCopy (DN_Str8Builder *builder, void const *ptr, DN_USize size); -DN_API bool DN_Str8Builder_AppendBuilderRef (DN_Str8Builder *dest, DN_Str8Builder const *src); -DN_API bool DN_Str8Builder_AppendBuilderCopy (DN_Str8Builder *dest, DN_Str8Builder const *src); -#define DN_Str8Builder_PrependArrayRef(builder, strings, size) DN_Str8Builder_AddArrayRef(builder, strings, size, DN_Str8BuilderAdd_Prepend) -#define DN_Str8Builder_PrependArrayCopy(builder, strings, size) DN_Str8Builder_AddArrayCopy(builder, strings, size, DN_Str8BuilderAdd_Prepend) -#define DN_Str8Builder_PrependSliceRef(builder, slice) DN_Str8Builder_AddArrayRef(builder, slice.data, slice.size, DN_Str8BuilderAdd_Prepend) -#define DN_Str8Builder_PrependSliceCopy(builder, slice) DN_Str8Builder_AddArrayCopy(builder, slice.data, slice.size, DN_Str8BuilderAdd_Prepend) -DN_API bool DN_Str8Builder_PrependRef (DN_Str8Builder *builder, DN_Str8 string); -DN_API bool DN_Str8Builder_PrependCopy (DN_Str8Builder *builder, DN_Str8 string); -#define DN_Str8Builder_PrependFV(builder, fmt, args) DN_Str8Builder_AddFV(builder, DN_Str8BuilderAdd_Prepend, fmt, args) -DN_API bool DN_Str8Builder_PrependF (DN_Str8Builder *builder, DN_FMT_ATTRIB char const *fmt, ...); -DN_API bool DN_Str8Builder_Erase (DN_Str8Builder *builder, DN_Str8 string); -DN_API DN_Str8 DN_Str8Builder_Build (DN_Str8Builder const *builder, DN_Arena *arena); -DN_API DN_Str8 DN_Str8Builder_BuildDelimited (DN_Str8Builder const *builder, DN_Str8 delimiter, DN_Arena *arena); -DN_API DN_Slice DN_Str8Builder_BuildSlice (DN_Str8Builder const *builder, DN_Arena *arena); - -DN_API bool DN_Char_IsAlphabet (char ch); -DN_API bool DN_Char_IsDigit (char ch); -DN_API bool DN_Char_IsAlphaNum (char ch); -DN_API bool DN_Char_IsWhitespace (char ch); -DN_API bool DN_Char_IsHex (char ch); -DN_API char DN_Char_ToHex (char ch); -DN_API char DN_Char_ToHexUnchecked (char ch); -DN_API char DN_Char_ToLower (char ch); -DN_API char DN_Char_ToUpper (char ch); - -DN_API int DN_UTF8_EncodeCodepoint (uint8_t utf8[4], uint32_t codepoint); -DN_API int DN_UTF16_EncodeCodepoint (uint16_t utf16[2], uint32_t codepoint); -#endif // !defined(DN_BASE_STRING_H) +#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 inlined this file => #include "Base/dn_base_containers.h" #if !defined(DN_CONTAINERS_H) #define DN_CONTAINERS_H @@ -3510,7 +3585,7 @@ template struct DN_List // ``` // MyStruct buffer[TB_ASType_Count] = {}; // DN_USize size = 0; -// MyStruct *item = DN_LArray_Make(buffer, size, DN_ArrayCountU(buffer), DN_ZeroMem_No); +// MyStruct *item = DN_LArray_Make(buffer, size, DN_ArrayCountU(buffer), DN_ZMem_No); // ``` // // IArray => Intrusive Array @@ -3523,7 +3598,7 @@ template struct DN_List // DN_USize max; // } my_array = {}; // -// MyStruct *item = DN_IArray_Make(&my_array, MyArray, DN_ZeroMem_No); +// MyStruct *item = DN_IArray_Make(&my_array, MyArray, DN_ZMem_No); // ``` // ISLList => Intrusive Singly Linked List // Define a struct with the members 'next': @@ -3544,13 +3619,13 @@ template struct DN_List #define DN_DLList_InitArena(list, T, arena) \ do { \ - (list) = DN_Arena_New(arena, T, DN_ZeroMem_Yes); \ + (list) = DN_ArenaNew(arena, T, DN_ZMem_Yes); \ DN_DLList_Init(list); \ } while (0) #define DN_DLList_InitPool(list, T, pool) \ do { \ - (list) = DN_Pool_New(pool, T); \ + (list) = DN_PoolNew(pool, T); \ DN_DLList_Init(list); \ } while (0) @@ -3612,10 +3687,10 @@ template struct DN_List #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, zero_mem) (decltype(&(c_array)[0])) DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), count, zero_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_ZeroMem_Yes) -#define DN_LArray_Make(c_array, size, max, zero_mem) (decltype(&(c_array)[0])) DN_CArray2_MakeArray(c_array, size, max, sizeof((c_array)[0]), 1, zero_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_ZeroMem_Yes) +#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) @@ -3630,10 +3705,10 @@ template struct DN_List #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, zero_mem) (decltype(&((array)->data)[0])) DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), count, zero_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_ZeroMem_Yes) -#define DN_IArray_Make(array, zero_mem) (decltype(&((array)->data)[0])) DN_CArray2_MakeArray((array)->data, &(array)->size, (array)->max, sizeof(((array)->data)[0]), 1, zero_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_ZeroMem_Yes) +#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) @@ -3646,7 +3721,7 @@ template struct DN_List #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_ZeroMem zero_mem); +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); @@ -3661,7 +3736,7 @@ DN_API void DN_Ring_Read (DN_Ring *ring, voi #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_ZeroMem zero_mem); +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); @@ -3669,9 +3744,9 @@ template DN_ArrayFindResult DN_CArray_ // NOTE: DN_SArray ///////////////////////////////////////////////////////////////////////////////// #if !defined(DN_NO_SARRAY) -template DN_SArray DN_SArray_Init (DN_Arena *arena, DN_USize size, DN_ZeroMem zero_mem); -template DN_SArray DN_SArray_InitSlice (DN_Arena *arena, DN_Slice slice, DN_USize size, DN_ZeroMem zero_mem); -template DN_SArray DN_SArray_InitCArray (DN_Arena *arena, T const (&array)[N], DN_USize size, DN_ZeroMem); +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); @@ -3681,8 +3756,8 @@ template T * DN_SArray_ #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_ZeroMem zero_mem); -template T * DN_SArray_Make (DN_SArray *array, DN_ZeroMem zero_mem); +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); @@ -3712,8 +3787,8 @@ template T * DN_FArray_ #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_ZeroMem zero_mem); -template T * DN_FArray_Make (DN_FArray *array, DN_ZeroMem zero_mem); +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); @@ -3735,7 +3810,7 @@ template DN_Slice DN_Slice_I 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_ZeroMem zero_mem); +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); @@ -3744,7 +3819,7 @@ template DN_Slice DN_Slice_A #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_ZeroMem zero_mem); +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); @@ -3786,104 +3861,6 @@ template void DN_List_Ad 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 inlined this file => #include "Base/dn_base_convert.h" -#if !defined(DN_BASE_CONVERT_H) -#define DN_BASE_CONVERT_H - -// DN: Single header generator commented out this header => #include "../dn_base_inc.h" - -struct DN_CVTU64Str8 -{ - char data[27 + 1]; // NOTE(dn): 27 is the maximum size of DN_U64 including a separator - DN_U8 size; -}; - -enum DN_CVTBytesType -{ - DN_CVTBytesType_B, - DN_CVTBytesType_KiB, - DN_CVTBytesType_MiB, - DN_CVTBytesType_GiB, - DN_CVTBytesType_TiB, - DN_CVTBytesType_Count, - DN_CVTBytesType_Auto, -}; - -struct DN_CVTU64Bytes -{ - DN_CVTBytesType type; - DN_Str8 suffix; // "KiB", "MiB", "GiB" .. e.t.c - DN_F64 bytes; -}; - -struct DN_CVTU64HexStr -{ - char data[2 /*0x*/ + 16 /*hex*/ + 1 /*null-terminator*/]; - DN_U8 size; -}; - -typedef DN_U32 DN_CVTU64HexStrFlags; -enum DN_CVTU64HexStrFlags_ -{ - DN_CVTU64HexStrFlags_Nil = 0, - DN_CVTU64HexStrFlags_0xPrefix = 1 << 0, /// Add the '0x' prefix from the string - DN_CVTU64HexStrFlags_UppercaseHex = 1 << 1, /// Use uppercase ascii characters for hex -}; - -typedef DN_U32 DN_CVTU64AgeUnit; -enum DN_CVTU64AgeUnit_ -{ - DN_CVTU64AgeUnit_Sec = 1 << 0, - DN_CVTU64AgeUnit_Min = 1 << 1, - DN_CVTU64AgeUnit_Hr = 1 << 2, - DN_CVTU64AgeUnit_Day = 1 << 3, - DN_CVTU64AgeUnit_Week = 1 << 4, - DN_CVTU64AgeUnit_Year = 1 << 5, - DN_CVTU64AgeUnit_HMS = DN_CVTU64AgeUnit_Sec | DN_CVTU64AgeUnit_Min | DN_CVTU64AgeUnit_Hr, - DN_CVTU64AgeUnit_All = DN_CVTU64AgeUnit_HMS | DN_CVTU64AgeUnit_Day | DN_CVTU64AgeUnit_Week | DN_CVTU64AgeUnit_Year, -}; - -struct DN_NibbleFromU8Result -{ - char nibble0; - char nibble1; -}; - -DN_API DN_NibbleFromU8Result DN_CVT_NibbleFromU8 (DN_U8 u8); -DN_API DN_U8 DN_CVT_U8FromHexNibble (char hex); - -DN_API int DN_CVT_FmtBuffer3DotTruncate (char *buffer, int size, DN_FMT_ATTRIB char const *fmt, ...); -DN_API DN_CVTU64Str8 DN_CVT_Str8FromU64 (DN_U64 val, char separator); -DN_API DN_CVTU64Bytes DN_CVT_BytesFromU64 (DN_U64 bytes, DN_CVTBytesType type); -#define DN_CVT_BytesFromU64Auto(bytes) DN_CVT_BytesFromU64(bytes, DN_CVTBytesType_Auto) -DN_API DN_Str8 DN_CVT_BytesStr8FromU64 (DN_Arena *arena, DN_U64 bytes, DN_CVTBytesType type); -#define DN_CVT_BytesStr8FromTLS(bytes, type) DN_CVT_BytesStr8FromU64(DN_OS_TLSTopArena(), bytes, type) -#define DN_CVT_BytesStr8FromU64Auto(arena, bytes) DN_CVT_BytesStr8FromU64(arena, bytes, DN_CVTBytesType_Auto) -#define DN_CVT_BytesStr8FromU64AutoTLS(bytes) DN_CVT_BytesStr8FromU64(DN_OS_TLSTopArena(), bytes, DN_CVTBytesType_Auto) -#define DN_CVT_BytesStr8FromU64Frame(bytes, type) DN_CVT_BytesStr8FromU64(DN_OS_TLSFrameArena(), bytes, type) -#define DN_CVT_BytesStr8FromU64AutoFrame(bytes) DN_CVT_BytesStr8FromU64(DN_OS_TLSFrameArena(), bytes, DN_CVTBytesType_Auto) -DN_API DN_Str8 DN_CVT_BytesTypeToStr8 (DN_CVTBytesType type); -DN_API DN_Str8 DN_CVT_AgeFromU64 (DN_Arena *arena, DN_U64 age_s, DN_CVTU64AgeUnit unit); -DN_API DN_Str8 DN_CVT_AgeFromF64 (DN_Arena *arena, DN_F64 age_s, DN_CVTU64AgeUnit unit); - -DN_API DN_U64 DN_CVT_U64FromHex (DN_Str8 hex); -DN_API DN_Str8 DN_CVT_HexFromU64 (DN_Arena *arena, DN_U64 number, DN_CVTU64HexStrFlags flags); -#define DN_CVT_HexFromU64Frame(number, flags) DN_CVT_HexFromU64(DN_OS_TLSFrameArena(), number, flags) -DN_API DN_CVTU64HexStr DN_CVT_HexFromU64Str (DN_U64 number, DN_CVTU64HexStrFlags flags); - -DN_API bool DN_CVT_HexFromBytesPtr (void const *src, DN_USize src_size, char *dest, DN_USize dest_size); -DN_API DN_Str8 DN_CVT_HexFromBytes (DN_Arena *arena, void const *src, DN_USize size); -#define DN_CVT_HexFromBytesTLS(...) DN_CVT_HexFromBytes(DN_OS_TLSTopArena(), __VA_ARGS__) -#define DN_CVT_HexFromBytesFrame(...) DN_CVT_HexFromBytes(DN_OS_TLSFrameArena(), __VA_ARGS__) - -DN_API DN_USize DN_CVT_BytesFromHexPtrUnchecked (DN_Str8 hex, void *dest, DN_USize dest_size); -DN_API DN_USize DN_CVT_BytesFromHexPtr (DN_Str8 hex, void *dest, DN_USize dest_size); -DN_API DN_Str8 DN_CVT_BytesFromHexUnchecked (DN_Arena *arena, DN_Str8 hex); -#define DN_CVT_BytesFromHexUncheckedFromTLS(...) DN_CVT_BytesFromHexUnchecked(DN_OS_TLSTopArena(), __VA_ARGS__) -DN_API DN_Str8 DN_CVT_BytesFromHex (DN_Arena *arena, DN_Str8 hex); -#define DN_CVT_BytesFromHexFrame(...) DN_CVT_BytesFromHex(DN_OS_TLSFrameArena(), __VA_ARGS__) -#define DN_CVT_BytesFromHexTLS(...) DN_CVT_BytesFromHex(DN_OS_TLSTopArena(), __VA_ARGS__) -#endif // defined(DN_BASE_CONVERT_H) #endif // !defined(DN_BASE_INC_H) #if !defined(DN_OS_INC_H) @@ -5652,7 +5629,7 @@ enum DN_OSFileAccess_ #else #define DN_OSPathSeperator "/" #endif - #define DN_OSPathSeperatorString DN_STR8(DN_OSPathSeperator) + #define DN_OSPathSeperatorString DN_Str8Lit(DN_OSPathSeperator) #endif struct DN_OSPathLink @@ -5736,7 +5713,7 @@ struct DN_OSConditionVariable DN_U64 handle; }; -// NOTE: DN_OSThread /////////////////////////////////////////////////////////////////////////////// +// NOTE: DN_OSThread typedef DN_I32(DN_OSThreadFunc)(struct DN_OSThread *); struct DN_OSThread @@ -5751,7 +5728,7 @@ struct DN_OSThread DN_OSSemaphore init_semaphore; }; -// NOTE: DN_OSHttp ///////////////////////////////////////////////////////////////////////////////// +// NOTE: DN_OSHttp enum DN_OSHttpRequestSecure { DN_OSHttpRequestSecure_No, @@ -5837,13 +5814,18 @@ DN_API void DN_OS_Init (D 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_ZeroMem zero_mem); +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 (); @@ -5937,8 +5919,8 @@ DN_API DN_Str8 DN_OS_PathF (D #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_STR8("/")) -#define DN_OS_PathBuildBackSlash(allocator, fs_path) DN_OS_PathBuildWithSeparator(allocator, fs_path, DN_STR8("\\")) +#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); @@ -5982,8 +5964,8 @@ DN_API DN_OSHttpResponse DN_OS_HttpRequest (D #if !defined(DN_OS_ALLOCATOR_H) #define DN_OS_ALLOCATOR_H -DN_API DN_Arena DN_Arena_FromHeap(DN_U64 size, DN_ArenaFlags flags); -DN_API DN_Arena DN_Arena_FromVMem(DN_U64 reserve, DN_U64 commit, DN_ArenaFlags flags); +DN_API DN_Arena DN_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 inlined this file => #include "OS/dn_os_containers.h" @@ -6019,8 +6001,8 @@ template T * DN_VArray_ #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_ZeroMem zero_mem); -template T * DN_VArray_Make (DN_VArray *array, DN_ZeroMem zero_mem); +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); @@ -6032,7 +6014,7 @@ template T * DN_VArray_ 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_ZeroMem zero_mem); +template void DN_VArray_Clear (DN_VArray *array, DN_ZMem z_mem); #endif // !defined(DN_OS_CONTAINERS_H) // DN: Single header generator inlined this file => #include "OS/dn_os_print.h" #if !defined(DN_OS_PRINT_H) @@ -6103,70 +6085,70 @@ DN_API void DN_OS_PrintLnFVStyle (DN_OSPrintDest dest, DN_LOGStyle style, // NOTE: DN_Str8 /////////////////////////////////////////////////////////////////////////////////// -DN_API DN_Str8 DN_Str8_FromFrameFV (DN_FMT_ATTRIB char const *fmt, va_list args); -DN_API DN_Str8 DN_Str8_FromFrameF (DN_FMT_ATTRIB char const *fmt, ...); -DN_API DN_Str8 DN_Str8_FromFrame (DN_USize size, DN_ZeroMem zero_mem); -DN_API DN_Str8 DN_Str8_FromHeapF (DN_FMT_ATTRIB char const *fmt, ...); -DN_API DN_Str8 DN_Str8_FromHeap (DN_USize size, DN_ZeroMem zero_mem); -DN_API DN_Str8 DN_Str8_FromTLSFV (DN_FMT_ATTRIB char const *fmt, va_list args); -DN_API DN_Str8 DN_Str8_FromTLSF (DN_FMT_ATTRIB char const *fmt, ...); -DN_API DN_Str8 DN_Str8_FromTLS (DN_USize size, DN_ZeroMem zero_mem); -DN_API DN_Str8 DN_Str8_FromStr8Frame (DN_Str8 string); -DN_API DN_Str8 DN_Str8_FromStr8TLS (DN_Str8 string); +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_Slice DN_Str8_SplitFromFrame (DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode); -DN_API DN_Slice DN_Str8_SplitFromTLS (DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode); +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_Str8_SegmentFromFrame (DN_Str8 src, DN_USize segment_size, char segment_char); -DN_API DN_Str8 DN_Str8_SegmentFromTLS (DN_Str8 src, DN_USize segment_size, char segment_char); +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_Str8_ReverseSegmentFromFrame (DN_Str8 src, DN_USize segment_size, char segment_char); -DN_API DN_Str8 DN_Str8_ReverseSegmentFromTLS (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_Str8_AppendFFromFrame (DN_Str8 string, char const *fmt, ...); -DN_API DN_Str8 DN_Str8_AppendFFromTLS (DN_Str8 string, char const *fmt, ...); +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_Str8_FillFFromFrame (DN_Str8 string, char const *fmt, ...); -DN_API DN_Str8 DN_Str8_FillFFromTLS (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_Str8DotTruncateResult DN_Str8_DotTruncateMiddleFromFrame (DN_Str8 str8, uint32_t side_size, DN_Str8 truncator); -DN_API DN_Str8DotTruncateResult DN_Str8_DotTruncateMiddleFromTLS (DN_Str8 str8, uint32_t side_size, DN_Str8 truncator); +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_Str8_PadNewLines (DN_Arena *arena, DN_Str8 src, DN_Str8 pad); -DN_API DN_Str8 DN_Str8_PadNewLinesFromFrame (DN_Str8 src, DN_Str8 pad); -DN_API DN_Str8 DN_Str8_PadNewLinesFromTLS (DN_Str8 src, DN_Str8 pad); +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_Str8_UpperFromFrame (DN_Str8 string); -DN_API DN_Str8 DN_Str8_UpperFromTLS (DN_Str8 string); +DN_API DN_Str8 DN_Str8UpperFromFrame (DN_Str8 string); +DN_API DN_Str8 DN_Str8UpperFromTLS (DN_Str8 string); -DN_API DN_Str8 DN_Str8_LowerFromFrame (DN_Str8 string); -DN_API DN_Str8 DN_Str8_LowerFromTLS (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_Str8_Replace (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_Str8_ReplaceInsensitive (DN_Str8 string, DN_Str8 find, DN_Str8 replace, DN_USize start_index, DN_Arena *arena); +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_Str8Builder_FromArena () { return DN_Str8Builder_FromArena(DN_OS_TLSGet()->frame_arena); } -DN_API DN_Str8Builder DN_Str8Builder_FromTLS () { return DN_Str8Builder_FromArena(DN_OS_TLSTopArena()); } +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_Str8Builder_FromStr8PtrRefFrame (DN_Str8 const *strings, DN_USize size) { return DN_Str8Builder_FromStr8PtrRef(DN_OS_TLSGet()->frame_arena, strings, size); } -DN_API DN_Str8Builder DN_Str8Builder_FromStr8PtrRefTLS (DN_Str8 const *strings, DN_USize size) { return DN_Str8Builder_FromStr8PtrRef(DN_OS_TLSTopArena(), strings, size); } -DN_API DN_Str8Builder DN_Str8Builder_FromStr8PtrCopyFrame (DN_Str8 const *strings, DN_USize size) { return DN_Str8Builder_FromStr8PtrCopy(DN_OS_TLSGet()->frame_arena, strings, size); } -DN_API DN_Str8Builder DN_Str8Builder_FromStr8PtrCopyTLS (DN_Str8 const *strings, DN_USize size) { return DN_Str8Builder_FromStr8PtrCopy(DN_OS_TLSTopArena(), strings, size); } +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_Str8Builder_FromBuilderFrame (DN_Str8Builder const *builder) { return DN_Str8Builder_FromBuilder(DN_OS_TLSGet()->frame_arena, builder); } -DN_API DN_Str8Builder DN_Str8Builder_FromBuilderTLS (DN_Str8Builder const *builder) { return DN_Str8Builder_FromBuilder(DN_OS_TLSTopArena(), builder); } +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_Str8Builder_BuildFromFrame (DN_Str8Builder const *builder) { return DN_Str8Builder_Build(builder, DN_OS_TLSGet()->frame_arena); } -DN_API DN_Str8 DN_Str8Builder_BuildFromHeap (DN_Str8Builder const *builder, DN_Arena *arena); -DN_API DN_Str8 DN_Str8Builder_BuildFromTLS (DN_Str8Builder const *builder) { return DN_Str8Builder_Build(builder, DN_OS_TLSTopArena()); } +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_Str8Builder_BuildDelimitedFromFrame(DN_Str8Builder const *builder, DN_Str8 delimiter) { return DN_Str8Builder_BuildDelimited(builder, delimiter, DN_OS_TLSGet()->frame_arena); } -DN_API DN_Str8 DN_Str8Builder_BuildDelimitedFromTLS (DN_Str8Builder const *builder, DN_Str8 delimiter) { return DN_Str8Builder_BuildDelimited(builder, delimiter, 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_Str8Builder_BuildSliceFromFrame (DN_Str8Builder const *builder) { return DN_Str8Builder_BuildSlice(builder, DN_OS_TLSGet()->frame_arena); } -DN_API DN_Slice DN_Str8Builder_BuildSliceFromTLS (DN_Str8Builder const *builder) { return DN_Str8Builder_BuildSlice(builder, 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) @@ -6253,7 +6235,7 @@ struct DN_Profiler }; #define DN_Profiler_ZoneLoop(prof, name, index) \ - DN_ProfilerZone DN_UniqueName(zone_) = DN_Profiler_BeginZone(prof, DN_STR8(name), index), DN_UniqueName(dummy_) = {}; \ + DN_ProfilerZone DN_UniqueName(zone_) = DN_Profiler_BeginZone(prof, DN_Str8Lit(name), index), DN_UniqueName(dummy_) = {}; \ DN_UniqueName(dummy_).begin_tsc == 0; \ DN_Profiler_EndZone(prof, DN_UniqueName(zone_)), DN_UniqueName(dummy_).begin_tsc = 1 @@ -6261,7 +6243,7 @@ struct DN_Profiler DN_API DN_Profiler DN_Profiler_Init (DN_ProfilerAnchor *anchors, DN_USize count, DN_USize anchors_per_frame, DN_ProfilerTSC tsc, DN_U64 tsc_frequency); DN_API DN_ProfilerZone DN_Profiler_BeginZone (DN_Profiler *profiler, DN_Str8 name, DN_U16 anchor_index); -#define DN_Profiler_BeginZoneAuto(prof, name) DN_Profiler_BeginZone(prof, DN_STR8(name), __COUNTER__ + 1) +#define DN_Profiler_BeginZoneAuto(prof, name) DN_Profiler_BeginZone(prof, DN_Str8Lit(name), __COUNTER__ + 1) DN_API void DN_Profiler_EndZone (DN_Profiler *profiler, DN_ProfilerZone zone); DN_API DN_USize DN_Profiler_FrameCount (DN_Profiler const *profiler); DN_API DN_ProfilerAnchorArray DN_Profiler_FrameAnchorsFromIndex (DN_Profiler *profiler, DN_USize frame_index); @@ -6848,7 +6830,7 @@ DN_API uint64_t DN_FNV1A64_Iterate (void const *bytes, DN_USize si 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]) +#define DN_MurmurHash3_x64U128AsU32(key, len, seed) (DN_Cast(uint32_t)DN_MurmurHash3_x64U128(key, len, seed).e[0]) #endif // !defined(DN_HASH_H) #if !defined(DN_HELPERS_H) @@ -6948,42 +6930,6 @@ struct DN_BinarySearchResult template using DN_QSortLessThanProc = bool(T const &a, T const &b, void *user_context); -// NOTE: Misc ////////////////////////////////////////////////////////////////////////////////////// -// NOTE: DN_JobQueue /////////////////////////////////////////////////////////////////////////////// -typedef void(DN_JobQueueFunc)(DN_OSThread *thread, void *user_context); -struct DN_Job -{ - DN_JobQueueFunc *func; // The function to invoke for the job - void *user_context; // Pointer user can set to use in their `job_func` - uint64_t elapsed_tsc; - uint16_t user_tag; // Arbitrary value the user can set to identiy the type of `user_context` this job has - bool add_to_completion_queue; // When true, on job completion, job must be dequeued from the completion queue via `GetFinishedJobs` -}; - -#if !defined(DN_JOB_QUEUE_SPMC_SIZE) - #define DN_JOB_QUEUE_SPMC_SIZE 128 -#endif - -struct DN_JobQueueSPMC -{ - DN_OSMutex mutex; - DN_OSSemaphore thread_wait_for_job_semaphore; - DN_OSSemaphore wait_for_completion_semaphore; - DN_U32 threads_waiting_for_completion; - - DN_Job jobs[DN_JOB_QUEUE_SPMC_SIZE]; - DN_B32 quit; - DN_U32 quit_exit_code; - DN_U32 volatile read_index; - DN_U32 volatile finish_index; - DN_U32 volatile write_index; - - DN_OSSemaphore complete_queue_write_semaphore; - DN_Job complete_queue[DN_JOB_QUEUE_SPMC_SIZE]; - DN_U32 volatile complete_read_index; - DN_U32 volatile complete_write_index; -}; - // NOTE: DN_PCG32 ////////////////////////////////////////////////////////////////////////////////// DN_API DN_PCG32 DN_PCG32_Init (uint64_t seed); DN_API uint32_t DN_PCG32_Next (DN_PCG32 *rng); @@ -7026,41 +6972,25 @@ DN_API void DN_JSONBuilder_I64Named (DN_JSONBuilde 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_STR8("")) -#define DN_JSONBuilder_ArrayBegin(builder) DN_JSONBuilder_ArrayBeginNamed(builder, DN_STR8("")) -#define DN_JSONBuilder_Str8(builder, value) DN_JSONBuilder_Str8Named(builder, DN_STR8(""), value) -#define DN_JSONBuilder_Literal(builder, value) DN_JSONBuilder_LiteralNamed(builder, DN_STR8(""), value) -#define DN_JSONBuilder_U64(builder, value) DN_JSONBuilder_U64Named(builder, DN_STR8(""), value) -#define DN_JSONBuilder_I64(builder, value) DN_JSONBuilder_I64Named(builder, DN_STR8(""), value) -#define DN_JSONBuilder_F64(builder, value) DN_JSONBuilder_F64Named(builder, DN_STR8(""), value) -#define DN_JSONBuilder_Bool(builder, value) DN_JSONBuilder_BoolNamed(builder, DN_STR8(""), 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 /////////////////////////////////////////////////////////////////////////// +// 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); +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 ////////////////////////////////////////////////////////////////////////////////// +// 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); +template void DN_QSort (T *array, DN_USize array_size, void *user_context, DN_QSortLessThanProc less_than = DN_QSort_DefaultLessThan); -// NOTE: DN_JobQueue /////////////////////////////////////////////////////////////////////////////// -DN_API DN_JobQueueSPMC DN_OS_JobQueueSPMCInit (); -DN_API bool DN_OS_JobQueueSPMCCanAdd (DN_JobQueueSPMC const *queue, uint32_t count); -DN_API bool DN_OS_JobQueueSPMCAddArray (DN_JobQueueSPMC *queue, DN_Job *jobs, uint32_t count); -DN_API bool DN_OS_JobQueueSPMCAdd (DN_JobQueueSPMC *queue, DN_Job job); -DN_API void DN_OS_JobQueueSPMCWaitForCompletion (DN_JobQueueSPMC *queue); -DN_API int32_t DN_OS_JobQueueSPMCThread (DN_OSThread *thread); -DN_API DN_USize DN_OS_JobQueueSPMCGetFinishedJobs (DN_JobQueueSPMC *queue, DN_Job *jobs, DN_USize jobs_size); - -// NOTE: DN_BinarySearch /////////////////////////////////////////////////////////////////////////// +// NOTE: DN_BinarySearch template bool DN_BinarySearch_DefaultLessThan(T const &lhs, T const &rhs) { diff --git a/Source/Base/dn_base.cpp b/Source/Base/dn_base.cpp index 74d42b5..98577c6 100644 --- a/Source/Base/dn_base.cpp +++ b/Source/Base/dn_base.cpp @@ -1550,20 +1550,16 @@ DN_API DN_USize DN_FmtVSize(DN_FMT_ATTRIB char const *fmt, va_list args) DN_API DN_USize DN_CStr8Size(char const *src) { DN_USize result = 0; - for (;src && src[0] != 0; src++, result++) { - src++; - result++; - } + for (; src && src[0] != 0; src++, result++) + ; return result; } DN_API DN_USize DN_CStr16Size(wchar_t const *src) { DN_USize result = 0; - while (src && src[0] != 0) { - src++; - result++; - } + for (; src && src[0] != 0; src++, result++) + ; return result; } diff --git a/Source/Core/dn_core_debug.cpp b/Source/Core/dn_core_debug.cpp index 8642ce4..b3907d2 100644 --- a/Source/Core/dn_core_debug.cpp +++ b/Source/Core/dn_core_debug.cpp @@ -394,7 +394,7 @@ DN_API DN_ProfilerZone DN_Profiler_BeginZone(DN_Profiler *profiler, DN_Str8 name // TODO: We need per-thread-local-storage profiler so that we can use these apis // across threads. For now, we let them overwrite each other but this is not tenable. #if 0 - if (DN_Str8HasData(anchor->name) && anchor->name != name) + if (anchor->name.size && anchor->name != name) DN_AssertF(name == anchor->name, "Potentially overwriting a zone by accident? Anchor is '%.*s', name is '%.*s'", DN_Str8PrintFmt(anchor->name), DN_Str8PrintFmt(name)); #endif diff --git a/Source/Core/dn_core_demo.cpp b/Source/Core/dn_core_demo.cpp index 0445a18..82fbb35 100644 --- a/Source/Core/dn_core_demo.cpp +++ b/Source/Core/dn_core_demo.cpp @@ -602,7 +602,7 @@ void DN_Docs_Demo() DN_ProfilerAnchor *read_anchors = DN_Profiler_ReadBuffer(); for (DN_USize index = 0; index < DN_PROFILER_ANCHOR_BUFFER_SIZE; index++) { DN_ProfilerAnchor *anchor = read_anchors + index; - if (DN_Str8HasData(anchor->name)) { + if (anchor->name.size) { // ... } } @@ -614,7 +614,7 @@ void DN_Docs_Demo() DN_ProfilerAnchor *write_anchors = DN_Profiler_WriteBuffer(); for (DN_USize index = 0; index < DN_PROFILER_ANCHOR_BUFFER_SIZE; index++) { DN_ProfilerAnchor *anchor = write_anchors + index; - if (DN_Str8HasData(anchor->name)) { + if (anchor->name.size) { // ... } } @@ -1039,7 +1039,7 @@ void DN_Docs_Demo() // NOTE: DN_Str8x32FromFmt { - DN_Str8x32 string = DN_Str8x32FromFmt("%" PRIu64, 123123); + DN_Str8x32 string = DN_Str8x32FromFmt("%d", 123123); if (0) // Prints "123123" printf("%.*s", DN_Str8PrintFmt(string)); } diff --git a/Source/Extra/dn_csv.cpp b/Source/Extra/dn_csv.cpp index b8652bb..fca9266 100644 --- a/Source/Extra/dn_csv.cpp +++ b/Source/Extra/dn_csv.cpp @@ -17,7 +17,7 @@ static bool DN_CSV_TokeniserValid(DN_CSVTokeniser *tokeniser) static bool DN_CSV_TokeniserNextRow(DN_CSVTokeniser *tokeniser) { bool result = false; - if (DN_CSV_TokeniserValid(tokeniser) && DN_Str8HasData(tokeniser->string)) { + if (DN_CSV_TokeniserValid(tokeniser) && tokeniser->string.size) { // NOTE: First time querying row iterator is nil, let tokeniser advance if (tokeniser->it) { // NOTE: Only advance the tokeniser if we're at the end of the line and @@ -39,7 +39,7 @@ static DN_Str8 DN_CSV_TokeniserNextField(DN_CSVTokeniser *tokeniser) if (!DN_CSV_TokeniserValid(tokeniser)) return result; - if (!DN_Str8HasData(tokeniser->string)) { + if (tokeniser->string.size == 0) { tokeniser->bad = true; return result; } @@ -146,7 +146,7 @@ static int DN_CSV_TokeniserNextN(DN_CSVTokeniser *tokeniser, DN_Str8 *fields, in int result = 0; for (; result < fields_size; result++) { fields[result] = column_iterator ? DN_CSV_TokeniserNextColumn(tokeniser) : DN_CSV_TokeniserNextField(tokeniser); - if (!DN_CSV_TokeniserValid(tokeniser) || !DN_Str8HasData(fields[result])) + if (!DN_CSV_TokeniserValid(tokeniser) || fields[result].size == 0) break; } @@ -176,8 +176,8 @@ static void DN_CSV_TokeniserSkipLineN(DN_CSVTokeniser *tokeniser, int count) static void DN_CSV_PackU64(DN_CSVPack *pack, DN_CSVSerialise serialise, DN_U64 *value) { if (serialise == DN_CSVSerialise_Read) { - DN_Str8 csv_value = DN_CSV_TokeniserNextColumn(&pack->read_tokeniser); - DN_Str8ToU64Result to_u64 = DN_Str8ToU64(csv_value, 0); + DN_Str8 csv_value = DN_CSV_TokeniserNextColumn(&pack->read_tokeniser); + DN_U64FromResult to_u64 = DN_U64FromStr8(csv_value, 0); DN_Assert(to_u64.success); *value = to_u64.value; } else { @@ -188,8 +188,8 @@ static void DN_CSV_PackU64(DN_CSVPack *pack, DN_CSVSerialise serialise, DN_U64 * static void DN_CSV_PackI64(DN_CSVPack *pack, DN_CSVSerialise serialise, DN_I64 *value) { if (serialise == DN_CSVSerialise_Read) { - DN_Str8 csv_value = DN_CSV_TokeniserNextColumn(&pack->read_tokeniser); - DN_Str8ToI64Result to_i64 = DN_Str8ToI64(csv_value, 0); + DN_Str8 csv_value = DN_CSV_TokeniserNextColumn(&pack->read_tokeniser); + DN_I64FromResult to_i64 = DN_I64FromStr8(csv_value, 0); DN_Assert(to_i64.success); *value = to_i64.value; } else { @@ -250,7 +250,7 @@ static void DN_CSV_PackStr8(DN_CSVPack *pack, DN_CSVSerialise serialise, DN_Str8 { if (serialise == DN_CSVSerialise_Read) { DN_Str8 csv_value = DN_CSV_TokeniserNextColumn(&pack->read_tokeniser); - *str8 = DN_Str8FromStr8(arena, csv_value); + *str8 = DN_Str8FromStr8Arena(arena, csv_value); } else { DN_Str8BuilderAppendF(&pack->write_builder, "%s%.*s", pack->write_column++ ? "," : "", DN_Str8PrintFmt(*str8)); } diff --git a/Source/Extra/dn_tests.cpp b/Source/Extra/dn_tests.cpp index 584648c..7b13c4d 100644 --- a/Source/Extra/dn_tests.cpp +++ b/Source/Extra/dn_tests.cpp @@ -239,10 +239,10 @@ static void DN_RefImpl_CPUReportDump() // Print out supported instruction set fe static DN_UTCore DN_Tests_Base() { DN_UTCore result = DN_UT_Init(); -#if defined(DN_PLATFORM_WIN32) && defined(DN_COMPILER_MSVC) - DN_RefImplCPUReport ref_cpu_report = DN_RefImplCPUReport_Init(); DN_UT_LogF(&result, "DN_Base\n"); { +#if defined(DN_PLATFORM_WIN32) && defined(DN_COMPILER_MSVC) + DN_RefImplCPUReport ref_cpu_report = DN_RefImplCPUReport_Init(); for (DN_UT_Test(&result, "Query CPUID")) { DN_CPUReport cpu_report = DN_CPUGetReport(); @@ -278,30 +278,30 @@ static DN_UTCore DN_Tests_Base() DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_SSE4A) == ref_cpu_report.SSE4a()); DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_SSSE3) == ref_cpu_report.SSSE3()); - // NOTE: Feature flags we haven't bothered detecting yet but are in MSDN's example ///////////// - #if 0 - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_ADX) == DN_RefImplCPUReport::ADX()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_BMI1) == DN_RefImplCPUReport::BMI1()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_BMI2) == DN_RefImplCPUReport::BMI2()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_CLFSH) == DN_RefImplCPUReport::CLFSH()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_CX8) == DN_RefImplCPUReport::CX8()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_ERMS) == DN_RefImplCPUReport::ERMS()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_FSGSBASE) == DN_RefImplCPUReport::FSGSBASE()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_FXSR) == DN_RefImplCPUReport::FXSR()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_HLE) == DN_RefImplCPUReport::HLE()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_INVPCID) == DN_RefImplCPUReport::INVPCID()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_LAHF) == DN_RefImplCPUReport::LAHF()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_LZCNT) == DN_RefImplCPUReport::LZCNT()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_MSR) == DN_RefImplCPUReport::MSR()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_OSXSAVE) == DN_RefImplCPUReport::OSXSAVE()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_PREFETCHWT1) == DN_RefImplCPUReport::PREFETCHWT1()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_RTM) == DN_RefImplCPUReport::RTM()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_SEP) == DN_RefImplCPUReport::SEP()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_SYSCALL) == DN_RefImplCPUReport::SYSCALL()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_TBM) == DN_RefImplCPUReport::TBM()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_XOP) == DN_RefImplCPUReport::XOP()); - DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_XSAVE) == DN_RefImplCPUReport::XSAVE()); - #endif + // NOTE: Feature flags we haven't bothered detecting yet but are in MSDN's example ///////////// + #if 0 + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_ADX) == DN_RefImplCPUReport::ADX()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_BMI1) == DN_RefImplCPUReport::BMI1()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_BMI2) == DN_RefImplCPUReport::BMI2()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_CLFSH) == DN_RefImplCPUReport::CLFSH()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_CX8) == DN_RefImplCPUReport::CX8()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_ERMS) == DN_RefImplCPUReport::ERMS()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_FSGSBASE) == DN_RefImplCPUReport::FSGSBASE()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_FXSR) == DN_RefImplCPUReport::FXSR()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_HLE) == DN_RefImplCPUReport::HLE()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_INVPCID) == DN_RefImplCPUReport::INVPCID()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_LAHF) == DN_RefImplCPUReport::LAHF()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_LZCNT) == DN_RefImplCPUReport::LZCNT()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_MSR) == DN_RefImplCPUReport::MSR()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_OSXSAVE) == DN_RefImplCPUReport::OSXSAVE()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_PREFETCHWT1) == DN_RefImplCPUReport::PREFETCHWT1()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_RTM) == DN_RefImplCPUReport::RTM()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_SEP) == DN_RefImplCPUReport::SEP()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_SYSCALL) == DN_RefImplCPUReport::SYSCALL()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_TBM) == DN_RefImplCPUReport::TBM()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_XOP) == DN_RefImplCPUReport::XOP()); + DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_XSAVE) == DN_RefImplCPUReport::XSAVE()); + #endif } #endif // defined(DN_PLATFORM_WIN32) && defined(DN_COMPILER_MSVC) @@ -309,6 +309,12 @@ static DN_UTCore DN_Tests_Base() char buffer[512]; DN_Arena arena = DN_ArenaFromBuffer(buffer, sizeof(buffer), DN_ArenaFlags_NoPoison | DN_ArenaFlags_AllocCanLeak); + // NOTE: CStr8Size + { + DN_USize size = DN_CStr8Size("hello"); + DN_UT_AssertF(&result, size == 5, "size=%zu", size); + } + // NOTE: Str8FromFmtArena { DN_Str8 str8 = DN_Str8FromFmtArena(&arena, "Foo Bar %d", 5); @@ -1667,7 +1673,7 @@ DN_Str8 const DN_UT_HASH_STRING_[] = void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 input_hex = DN_CVT_HexFromBytes(tmem.arena, input.data, input.size); + DN_Str8 input_hex = DN_HexFromBytesPtrArena(input.data, input.size, tmem.arena); switch (hash_type) { case Hash_SHA3_224: { diff --git a/Source/OS/dn_os_posix.cpp b/Source/OS/dn_os_posix.cpp index b113f4e..ed1385b 100644 --- a/Source/OS/dn_os_posix.cpp +++ b/Source/OS/dn_os_posix.cpp @@ -196,7 +196,7 @@ DN_API DN_OSDiskSpace DN_OS_DiskSpace(DN_Str8 path) { DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr); DN_OSDiskSpace result = {}; - DN_Str8 path_z_terminated = DN_Str8FromStr8(tmem.arena, path); + DN_Str8 path_z_terminated = DN_Str8FromStr8Arena(tmem.arena, path); struct statvfs info = {}; if (statvfs(path_z_terminated.data, &info) != 0) @@ -598,7 +598,7 @@ DN_API bool DN_OS_PathMakeDir(DN_Str8 path) DN_USize path_indexes_size = 0; uint16_t path_indexes[64] = {}; - DN_Str8 copy = DN_Str8FromStr8(tmem.arena, path); + DN_Str8 copy = DN_Str8FromStr8Arena(tmem.arena, path); for (DN_USize index = copy.size - 1; index < copy.size; index--) { bool first_char = index == (copy.size - 1); char ch = copy.data[index]; @@ -910,7 +910,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, for (DN_ForIndexU(arg_index, cmd_line.size)) { DN_Str8 arg = cmd_line.data[arg_index]; - argv[arg_index] = DN_Str8FromStr8(tmem.arena, arg).data; // NOTE: Copy string to guarantee it is null-terminated + argv[arg_index] = DN_Str8FromStr8Arena(tmem.arena, arg).data; // NOTE: Copy string to guarantee it is null-terminated } // NOTE: Change the working directory if there is one @@ -928,7 +928,7 @@ DN_API DN_OSExecAsyncHandle DN_OS_ExecAsync(DN_Slice cmd_line, if (args->working_dir.size) { prev_working_dir = get_current_dir_name(); - DN_Str8 working_dir = DN_Str8FromStr8(tmem.arena, args->working_dir); + DN_Str8 working_dir = DN_Str8FromStr8Arena(tmem.arena, args->working_dir); if (chdir(working_dir.data) == -1) { result.os_error_code = errno; DN_OS_ErrSinkAppendF( @@ -1294,7 +1294,7 @@ DN_API void DN_Posix_ThreadSetName(DN_Str8 name) (void)name; #else DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr); - DN_Str8 copy = DN_Str8FromStr8(tmem.arena, name); + DN_Str8 copy = DN_Str8FromStr8Arena(tmem.arena, name); pthread_t thread = pthread_self(); pthread_setname_np(thread, (char *)copy.data); #endif @@ -1340,23 +1340,23 @@ DN_API DN_POSIXProcSelfStatus DN_Posix_ProcSelfStatus() result.name_size = DN_Min(str8.size, sizeof(result.name)); DN_Memcpy(result.name, str8.data, result.name_size); } else if (DN_Str8StartsWith(line, PID, DN_Str8EqCase_Insensitive)) { - DN_Str8 str8 = DN_Str8TrimWhitespaceAround(DN_Str8Slice(line, PID.size, line.size)); - DN_Str8ToU64Result to_u64 = DN_Str8ToU64(str8, 0); - result.pid = to_u64.value; + DN_Str8 str8 = DN_Str8TrimWhitespaceAround(DN_Str8Slice(line, PID.size, line.size)); + DN_U64FromResult to_u64 = DN_U64FromStr8(str8, 0); + result.pid = to_u64.value; DN_Assert(to_u64.success); } else if (DN_Str8StartsWith(line, VM_SIZE, DN_Str8EqCase_Insensitive)) { DN_Str8 size_with_kb = DN_Str8TrimWhitespaceAround(DN_Str8Slice(line, VM_SIZE.size, line.size)); DN_Assert(DN_Str8EndsWith(size_with_kb, DN_Str8Lit("kB"))); - DN_Str8 vm_size = DN_Str8BSplit(size_with_kb, DN_Str8Lit(" ")).lhs; - DN_Str8ToU64Result to_u64 = DN_Str8ToU64(vm_size, 0); - result.vm_size = DN_Kilobytes(to_u64.value); + DN_Str8 vm_size = DN_Str8BSplit(size_with_kb, DN_Str8Lit(" ")).lhs; + DN_U64FromResult to_u64 = DN_U64FromStr8(vm_size, 0); + result.vm_size = DN_Kilobytes(to_u64.value); DN_Assert(to_u64.success); } else if (DN_Str8StartsWith(line, VM_PEAK, DN_Str8EqCase_Insensitive)) { DN_Str8 size_with_kb = DN_Str8TrimWhitespaceAround(DN_Str8Slice(line, VM_PEAK.size, line.size)); DN_Assert(DN_Str8EndsWith(size_with_kb, DN_Str8Lit("kB"))); - DN_Str8 vm_size = DN_Str8BSplit(size_with_kb, DN_Str8Lit(" ")).lhs; - DN_Str8ToU64Result to_u64 = DN_Str8ToU64(vm_size, 0); - result.vm_peak = DN_Kilobytes(to_u64.value); + DN_Str8 vm_size = DN_Str8BSplit(size_with_kb, DN_Str8Lit(" ")).lhs; + DN_U64FromResult to_u64 = DN_U64FromStr8(vm_size, 0); + result.vm_peak = DN_Kilobytes(to_u64.value); DN_Assert(to_u64.success); } } diff --git a/Source/Standalone/dn_keccak.h b/Source/Standalone/dn_keccak.h index 90c7f44..d1ecb99 100644 --- a/Source/Standalone/dn_keccak.h +++ b/Source/Standalone/dn_keccak.h @@ -227,7 +227,7 @@ DN_KCBytes32 DN_KC_Keccak256(void const *src, uint64_t size); DN_KCBytes48 DN_KC_Keccak384(void const *src, uint64_t size); DN_KCBytes64 DN_KC_Keccak512(void const *src, uint64_t size); -#if defined(DN_BASE_STRING_H) +#if defined(DN_BASE_H) // NOTE: SHA3 - Helpers for DN data structures //////////////////////////////////////////////////// DN_KCBytes28 DN_KC_SHA3_224Str8(DN_Str8 string); DN_KCBytes32 DN_KC_SHA3_256Str8(DN_Str8 string); @@ -239,7 +239,7 @@ DN_KCBytes28 DN_KC_Keccak224Str8(DN_Str8 string); DN_KCBytes32 DN_KC_Keccak256Str8(DN_Str8 string); DN_KCBytes48 DN_KC_Keccak384Str8(DN_Str8 string); DN_KCBytes64 DN_KC_Keccak512Str8(DN_Str8 string); -#endif // DN_BASE_STRING_H +#endif // DN_BASE_H // NOTE: Helper functions ////////////////////////////////////////////////////////////////////////// // Convert a binary buffer into its hex representation into dest. The dest @@ -262,13 +262,13 @@ int DN_KC_Bytes32Equals(DN_KCBytes32 const *a, DN_KCBytes32 const *b); int DN_KC_Bytes48Equals(DN_KCBytes48 const *a, DN_KCBytes48 const *b); int DN_KC_Bytes64Equals(DN_KCBytes64 const *a, DN_KCBytes64 const *b); -#if defined(DN_BASE_STRING_H) +#if defined(DN_BASE_H) // NOTE: Other helper functions for DN data structures //////////////////////////////////////////// // Converts a 64 character hex string into the 32 byte binary representation. // Invalid hex characters in the string will be represented as 0. // hex: Must be exactly a 64 character hex string. DN_KCBytes32 DN_KC_Hex64ToBytes(DN_Str8 hex); -#endif // DN_BASE_STRING_H +#endif // DN_BASE_H #endif // DN_KC_H #if defined(DN_KC_IMPLEMENTATION) @@ -518,7 +518,7 @@ DN_KCBytes64 DN_KC_Keccak512(void const *src, size_t size) return result; } -#if defined(DN_BASE_STRING_H) +#if defined(DN_BASE_H) // NOTE: SHA3 - Helpers for DN data structures //////////////////////////////////////////////////// DN_KCBytes28 DN_KC_SHA3_224Str8(DN_Str8 string) { @@ -547,9 +547,9 @@ DN_KCBytes64 DN_KC_SHA3_512Str8(DN_Str8 string) DN_KC_SHA3_512Ptr(string.data, string.size, result.data, sizeof(result)); return result; } -#endif // DN_BASE_STRING_H +#endif // DN_BASE_H -#if defined(DN_BASE_STRING_H) +#if defined(DN_BASE_H) // NOTE: Keccak - Helpers for DN data structures ////////////////////////////////////////////////// DN_KCBytes28 DN_KC_Keccak224Str8(DN_Str8 string) { @@ -578,7 +578,7 @@ DN_KCBytes64 DN_KC_Keccak512Str8(DN_Str8 string) DN_KC_Keccak512Ptr(string.data, string.size, result.data, sizeof(result)); return result; } -#endif // DN_BASE_STRING_H +#endif // DN_BASE_H // NOTE: Helper functions ////////////////////////////////////////////////////////////////////////// void DN_KC_HexFromBytes(void const *src, size_t src_size, char *dest, size_t dest_size) @@ -653,14 +653,14 @@ int DN_KC_Bytes64Equals(DN_KCBytes64 const *a, DN_KCBytes64 const *b) return result; } -#if defined(DN_BASE_STRING_H) +#if defined(DN_BASE_H) // NOTE: Other helper functions for DN data structures //////////////////////////////////////////// DN_KCBytes32 DN_KC_Hex64ToBytes(DN_Str8 hex) { DN_KC_ASSERT(hex.size == 64); DN_KCBytes32 result; - DN_CVT_BytesFromHexPtr(hex, result.data, sizeof(result)); + DN_BytesFromHexStr8(hex, result.data, sizeof(result)); return result; } -#endif // DN_BASE_STRING_H +#endif // DN_BASE_H #endif // DN_KC_IMPLEMENTATION diff --git a/single_header_generator.cpp b/single_header_generator.cpp index 46bce54..8c4ad70 100644 --- a/single_header_generator.cpp +++ b/single_header_generator.cpp @@ -36,19 +36,19 @@ static void AppendCppFileLineByLine(DN_Str8Builder *dest, DN_Str8 cpp_path) DN_OS_ErrSinkEndAndExitIfErrorF(err, -1, "Failed to load file from '%S' for appending", cpp_path); for (DN_Str8 inc_walker = buffer;;) { - DN_Str8BSplitResult split = DN_Str8_BSplit(inc_walker, DN_STR8("\n")); - if (!DN_Str8_HasData(split.lhs)) + DN_Str8BSplitResult split = DN_Str8BSplit(inc_walker, DN_Str8Lit("\n")); + if (split.lhs.size == 0) break; inc_walker = split.rhs; // NOTE: Trim the whitespace, mainly for windows, the file we read will have \r\n whereas we just want to emit \n - DN_Str8 line = DN_Str8_TrimTailWhitespace(split.lhs); + DN_Str8 line = DN_Str8TrimTailWhitespace(split.lhs); // NOTE: Comment out any #include "../dn_.*" matches if we encounter one - DN_Str8FindResult find = DN_Str8_FindStr8(line, DN_STR8("#include \"../dn_"), DN_Str8EqCase_Sensitive); + DN_Str8FindResult find = DN_Str8FindStr8(line, DN_Str8Lit("#include \"../dn_"), DN_Str8EqCase_Sensitive); { if (find.found) { - line = DN_Str8_FromTLSF("%S// DN: Single header generator commented out this header => %S", find.start_to_before_match, DN_Str8_TrimWhitespaceAround(find.match_to_end_of_buffer)); + line = DN_Str8FromTLSF("%S// DN: Single header generator commented out this header => %S", find.start_to_before_match, DN_Str8TrimWhitespaceAround(find.match_to_end_of_buffer)); // The only time we use '../dn_.*' is for LSP purposes, so we // don't care about inlining it, hence we don't set 'include_file' @@ -59,17 +59,17 @@ static void AppendCppFileLineByLine(DN_Str8Builder *dest, DN_Str8 cpp_path) // (Right now DN only includes stb_sprintf with a relative path) DN_Str8 extra_include_path = {}; if (!find.found) { - find = DN_Str8_FindStr8(line, DN_STR8("#include \""), DN_Str8EqCase_Sensitive); + find = DN_Str8FindStr8(line, DN_Str8Lit("#include \""), DN_Str8EqCase_Sensitive); if (find.found) { - line = DN_Str8_FromTLSF("%S// DN: Single header generator commented out this header => %S", find.start_to_before_match, DN_Str8_TrimWhitespaceAround(find.match_to_end_of_buffer)); - DN_Str8 rel_include_path = DN_Str8_TrimWhitespaceAround(find.after_match_to_end_of_buffer); - DN_Str8 root_dir = DN_Str8_FileDirectoryFromPath(cpp_path); - extra_include_path = DN_OS_PathFFromTLS("%S/%S", root_dir, DN_Str8_TrimSuffix(rel_include_path, DN_STR8("\""))); + line = DN_Str8FromTLSF("%S// DN: Single header generator commented out this header => %S", find.start_to_before_match, DN_Str8TrimWhitespaceAround(find.match_to_end_of_buffer)); + DN_Str8 rel_include_path = DN_Str8TrimWhitespaceAround(find.after_match_to_end_of_buffer); + DN_Str8 root_dir = DN_Str8FileDirectoryFromPath(cpp_path); + extra_include_path = DN_OS_PathFFromTLS("%S/%S", root_dir, DN_Str8TrimSuffix(rel_include_path, DN_Str8Lit("\""))); } } - DN_Str8Builder_AppendRef(dest, line); - DN_Str8Builder_AppendRef(dest, DN_STR8("\n")); + DN_Str8BuilderAppendRef(dest, line); + DN_Str8BuilderAppendRef(dest, DN_Str8Lit("\n")); if (extra_include_path.size) AppendCppFileLineByLine(dest, extra_include_path); @@ -88,25 +88,25 @@ int main(int argc, char **argv) return -1; } - DN_Str8 dn_root_dir = DN_Str8_FromCStr8(argv[1]); - DN_Str8 output_dir = DN_Str8_FromCStr8(argv[2]); + DN_Str8 dn_root_dir = DN_Str8FromCStr8(argv[1]); + DN_Str8 output_dir = DN_Str8FromCStr8(argv[2]); if (!DN_OS_PathMakeDir(output_dir)) { DN_OS_PrintErrF("Failed to make requested output directory: %S", output_dir); return -1; } File const FILES[] = { - {FileType_Header, DN_STR8("dn_base_inc.h")}, - {FileType_Header, DN_STR8("dn_os_inc.h")}, - {FileType_Header, DN_STR8("dn_core_inc.h")}, - {FileType_Impl, DN_STR8("dn_base_inc.cpp")}, - {FileType_Impl, DN_STR8("dn_os_inc.cpp")}, - {FileType_Impl, DN_STR8("dn_core_inc.cpp")}, + {FileType_Header, DN_Str8Lit("dn_base_inc.h")}, + {FileType_Header, DN_Str8Lit("dn_os_inc.h")}, + {FileType_Header, DN_Str8Lit("dn_core_inc.h")}, + {FileType_Impl, DN_Str8Lit("dn_base_inc.cpp")}, + {FileType_Impl, DN_Str8Lit("dn_os_inc.cpp")}, + {FileType_Impl, DN_Str8Lit("dn_core_inc.cpp")}, }; for (DN_ForIndexU(type, FileType_Count)) { DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr); - DN_Str8Builder builder = DN_Str8Builder_FromTLS(); + DN_Str8Builder builder = DN_Str8BuilderFromTLS(); for (DN_ForItCArray(it, File const, FILES)) { if (it.data->type != type) continue; @@ -120,29 +120,29 @@ int main(int argc, char **argv) // NOTE: Walk the top-level dn_*_inc.[h|cpp] files for (DN_Str8 walker = file_buffer;;) { - DN_Str8BSplitResult split = DN_Str8_BSplit(walker, DN_STR8("\n")); - if (!DN_Str8_HasData(split.lhs)) + DN_Str8BSplitResult split = DN_Str8BSplit(walker, DN_Str8Lit("\n")); + if (split.lhs.size == 0) break; // NOTE: Parse the line, if it was a #include, extract it into this string DN_Str8 include_file = {}; { walker = split.rhs; - DN_Str8 line = DN_Str8_TrimTailWhitespace(split.lhs); + DN_Str8 line = DN_Str8TrimTailWhitespace(split.lhs); // NOTE: Comment out any #include "dn_.*" matches if we encounter one - DN_Str8FindResult find = DN_Str8_FindStr8(line, DN_STR8("#include \""), DN_Str8EqCase_Sensitive); + DN_Str8FindResult find = DN_Str8FindStr8(line, DN_Str8Lit("#include \""), DN_Str8EqCase_Sensitive); { - if (find.found && DN_Str8_FindStr8(line, DN_STR8("dn_"), DN_Str8EqCase_Sensitive).found) { - line = DN_Str8_FromTLSF("%S// DN: Single header generator inlined this file => %S", find.start_to_before_match, DN_Str8_TrimWhitespaceAround(find.match_to_end_of_buffer)); - include_file = DN_Str8_BSplit(find.after_match_to_end_of_buffer, DN_STR8("\"")).lhs; + if (find.found && DN_Str8FindStr8(line, DN_Str8Lit("dn_"), DN_Str8EqCase_Sensitive).found) { + line = DN_Str8FromTLSF("%S// DN: Single header generator inlined this file => %S", find.start_to_before_match, DN_Str8TrimWhitespaceAround(find.match_to_end_of_buffer)); + include_file = DN_Str8BSplit(find.after_match_to_end_of_buffer, DN_Str8Lit("\"")).lhs; DN_Assert(include_file.size); } } // NOTE: Record the line - DN_Str8Builder_AppendRef(&builder, line); - DN_Str8Builder_AppendRef(&builder, DN_STR8("\n")); + DN_Str8BuilderAppendRef(&builder, line); + DN_Str8BuilderAppendRef(&builder, DN_Str8Lit("\n")); } if (include_file.size) { // NOTE: If the line was a include file, we will inline the included file @@ -154,23 +154,23 @@ int main(int argc, char **argv) } DN_Str8 extra_files[] = { - DN_STR8("Extra/dn_math"), - DN_STR8("Extra/dn_async"), - DN_STR8("Extra/dn_bin_pack"), - DN_STR8("Extra/dn_csv"), - DN_STR8("Extra/dn_hash"), - DN_STR8("Extra/dn_helpers"), + DN_Str8Lit("Extra/dn_math"), + DN_Str8Lit("Extra/dn_async"), + DN_Str8Lit("Extra/dn_bin_pack"), + DN_Str8Lit("Extra/dn_csv"), + DN_Str8Lit("Extra/dn_hash"), + DN_Str8Lit("Extra/dn_helpers"), }; - DN_Str8 suffix = type == FileType_Header ? DN_STR8("h") : DN_STR8("cpp"); + DN_Str8 suffix = type == FileType_Header ? DN_Str8Lit("h") : DN_Str8Lit("cpp"); for (DN_ForItCArray(extra_it, DN_Str8, extra_files)) { DN_Str8 extra_path = DN_OS_PathFFromTLS("%S/%S.%S", dn_root_dir, *extra_it.data, suffix); AppendCppFileLineByLine(&builder, extra_path); } DN_OSDateTime date = DN_OS_DateLocalTimeNow(); - DN_Str8Builder_PrependF(&builder, "// Generated by the DN single header generator %04u-%02u-%02u %02u:%02u:%02u\n\n", date.year, date.month, date.day, date.hour, date.minutes, date.seconds); + DN_Str8BuilderPrependF(&builder, "// Generated by the DN single header generator %04u-%02u-%02u %02u:%02u:%02u\n\n", date.year, date.month, date.day, date.hour, date.minutes, date.seconds); - DN_Str8 buffer = DN_Str8_TrimWhitespaceAround(DN_Str8Builder_BuildFromTLS(&builder)); + DN_Str8 buffer = DN_Str8TrimWhitespaceAround(DN_Str8BuilderBuildFromTLS(&builder)); DN_Str8 single_header_path = DN_OS_PathFFromTLS("%S/dn_single_header.%S", output_dir, suffix); DN_OSErrSink *err = DN_OS_ErrSinkBeginDefault(); DN_OS_FileWriteAllSafe(single_header_path, buffer, err);