diff --git a/Source/Base/dn_base.cpp b/Source/Base/dn_base.cpp index 6ed7f07..a7dd58f 100644 --- a/Source/Base/dn_base.cpp +++ b/Source/Base/dn_base.cpp @@ -2,6 +2,12 @@ #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 @@ -19,7 +25,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; @@ -63,7 +69,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; @@ -113,7 +119,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); } @@ -126,9 +132,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 = {}; @@ -177,7 +183,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; @@ -236,7 +242,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; @@ -298,7 +304,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; } @@ -350,31 +356,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; } @@ -383,56 +389,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; } @@ -440,25 +446,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; } @@ -468,35 +474,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; } @@ -507,9 +513,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; } @@ -519,9 +525,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; } @@ -531,9 +537,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; } @@ -543,9 +549,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; } @@ -555,9 +561,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; } @@ -570,37 +576,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; } @@ -610,9 +616,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; } @@ -622,9 +628,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; } @@ -634,9 +640,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; } @@ -646,9 +652,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; } @@ -658,9 +664,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; } @@ -670,23 +676,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; } @@ -696,9 +702,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; } @@ -710,7 +716,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; } @@ -719,7 +725,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; } @@ -769,3 +775,2074 @@ 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++) { + 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++; + } + 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_FmtVAppend(result.data, &result.size, result.size + 1, fmt, args); + 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_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; +} diff --git a/Source/Base/dn_base.h b/Source/Base/dn_base.h index 9f70e7a..cd6d7fd 100644 --- a/Source/Base/dn_base.h +++ b/Source/Base/dn_base.h @@ -22,6 +22,7 @@ #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_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)) @@ -83,7 +84,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) @@ -95,12 +96,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) @@ -161,10 +162,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 @@ -173,21 +174,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 @@ -208,7 +224,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) @@ -247,7 +263,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) @@ -404,92 +420,638 @@ 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); +struct DN_U64FromResult +{ + bool success; + DN_U64 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 (); +struct DN_I64FromResult +{ + bool success; + DN_I64 value; +}; -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); +enum DN_MemCommit +{ + DN_MemCommit_No, + DN_MemCommit_Yes, +}; -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) +typedef DN_U32 DN_MemPage; +enum DN_MemPage_ +{ + // Exception on read/write with a page. This flag overrides the read/write + // access. + DN_MemPage_NoAccess = 1 << 0, -DN_API DN_I64 DN_SafeAddI64 (DN_I64 a, DN_I64 b); -DN_API DN_I64 DN_SafeMulI64 (DN_I64 a, DN_I64 b); + DN_MemPage_Read = 1 << 1, // Only read permitted on the page. -DN_API DN_U64 DN_SafeAddU64 (DN_U64 a, DN_U64 b); -DN_API DN_U64 DN_SafeMulU64 (DN_U64 a, DN_U64 b); + // Only write permitted on the page. On Windows this is not supported and + // will be promoted to read+write permissions. + DN_MemPage_Write = 1 << 2, -DN_API DN_U64 DN_SafeSubU64 (DN_U64 a, DN_U64 b); -DN_API DN_U32 DN_SafeSubU32 (DN_U32 a, DN_U32 b); + DN_MemPage_ReadWrite = DN_MemPage_Read | DN_MemPage_Write, -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); + // Modifier used in conjunction with previous flags. Raises exception on + // first access to the page, then, the underlying protection flags are + // active. This is supported on Windows, on other OS's using this flag will + // set the OS equivalent of DN_MemPage_NoAccess. + // This flag must only be used in DN_Mem_Protect + DN_MemPage_Guard = 1 << 3, -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); + // If leak tracing is enabled, this flag will allow the allocation recorded + // from the reserve call to be leaked, e.g. not printed when leaks are + // dumped to the console. + DN_MemPage_AllocRecordLeakPermitted = 1 << 4, -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); + // If leak tracing is enabled this flag will prevent any allocation record + // from being created in the allocation table at all. If this flag is + // enabled, 'OSMemPage_AllocRecordLeakPermitted' has no effect since the + // record will never be created. + DN_MemPage_NoAllocRecordEntry = 1 << 5, -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); + // [INTERNAL] Do not use. All flags together do not constitute a correct + // configuration of pages. + DN_MemPage_All = DN_MemPage_NoAccess | + DN_MemPage_ReadWrite | + DN_MemPage_Guard | + DN_MemPage_AllocRecordLeakPermitted | + DN_MemPage_NoAllocRecordEntry, +}; -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); +#if !defined(DN_ARENA_RESERVE_SIZE) + #define DN_ARENA_RESERVE_SIZE DN_Megabytes(64) +#endif -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); +#if !defined(DN_ARENA_COMMIT_SIZE) + #define DN_ARENA_COMMIT_SIZE DN_Kilobytes(64) +#endif -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); +enum DN_Allocator +{ + DN_Allocator_Arena, + DN_Allocator_Pool, +}; -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); +struct DN_ArenaBlock +{ + DN_ArenaBlock *prev; + DN_U64 used; + DN_U64 commit; + DN_U64 reserve; + DN_U64 reserve_sum; +}; -DN_API void DN_ASanPoisonMemoryRegion (void const volatile *ptr, DN_USize size); -DN_API void DN_ASanUnpoisonMemoryRegion(void const volatile *ptr, DN_USize size); +typedef DN_U32 DN_ArenaFlags; +enum DN_ArenaFlags_ +{ + DN_ArenaFlags_Nil = 0, + DN_ArenaFlags_NoGrow = 1 << 0, + DN_ArenaFlags_NoPoison = 1 << 1, + DN_ArenaFlags_NoAllocTrack = 1 << 2, + DN_ArenaFlags_AllocCanLeak = 1 << 3, -DN_API DN_F32 DN_EpsilonClampF32 (DN_F32 value, DN_F32 target, DN_F32 epsilon); + // NOTE: Internal flags. Do not use + DN_ArenaFlags_UserBuffer = 1 << 4, + DN_ArenaFlags_MemFuncs = 1 << 5, +}; + +struct DN_ArenaInfo +{ + DN_U64 used; + DN_U64 commit; + DN_U64 reserve; + DN_U64 blocks; +}; + +struct DN_ArenaStats +{ + DN_ArenaInfo info; + DN_ArenaInfo hwm; +}; + +enum DN_ArenaMemFuncType +{ + DN_ArenaMemFuncType_Nil, + DN_ArenaMemFuncType_Basic, + DN_ArenaMemFuncType_VMem, +}; + +typedef void *(DN_ArenaMemBasicAllocFunc)(DN_USize size); +typedef void (DN_ArenaMemBasicDeallocFunc)(void *ptr); +typedef void *(DN_ArenaMemVMemReserveFunc)(DN_USize size, DN_MemCommit commit, DN_MemPage page_flags); +typedef bool (DN_ArenaMemVMemCommitFunc)(void *ptr, DN_USize size, DN_U32 page_flags); +typedef void (DN_ArenaMemVMemReleaseFunc)(void *ptr, DN_USize size); +struct DN_ArenaMemFuncs +{ + DN_ArenaMemFuncType type; + DN_ArenaMemBasicAllocFunc *basic_alloc; + DN_ArenaMemBasicDeallocFunc *basic_dealloc; + + DN_U32 vmem_page_size; + DN_ArenaMemVMemReserveFunc *vmem_reserve; + DN_ArenaMemVMemCommitFunc *vmem_commit; + DN_ArenaMemVMemReleaseFunc *vmem_release; +}; + +struct DN_Arena +{ + DN_ArenaMemFuncs mem_funcs; + DN_ArenaBlock *curr; + DN_ArenaStats stats; + DN_ArenaFlags flags; + DN_Str8 label; + DN_Arena *prev, *next; +}; + +struct DN_ArenaTempMem +{ + DN_Arena *arena; + DN_U64 used_sum; +}; + +struct DN_ArenaTempMemScope +{ + DN_ArenaTempMemScope(DN_Arena *arena); + ~DN_ArenaTempMemScope(); + DN_ArenaTempMem mem; +}; + +DN_USize const DN_ARENA_HEADER_SIZE = DN_AlignUpPowerOfTwo(sizeof(DN_Arena), 64); + +#if !defined(DN_POOL_DEFAULT_ALIGN) + #define DN_POOL_DEFAULT_ALIGN 16 +#endif + +struct DN_PoolSlot +{ + void *data; + DN_PoolSlot *next; +}; + +enum DN_PoolSlotSize +{ + DN_PoolSlotSize_32B, + DN_PoolSlotSize_64B, + DN_PoolSlotSize_128B, + DN_PoolSlotSize_256B, + DN_PoolSlotSize_512B, + DN_PoolSlotSize_1KiB, + DN_PoolSlotSize_2KiB, + DN_PoolSlotSize_4KiB, + DN_PoolSlotSize_8KiB, + DN_PoolSlotSize_16KiB, + DN_PoolSlotSize_32KiB, + DN_PoolSlotSize_64KiB, + DN_PoolSlotSize_128KiB, + DN_PoolSlotSize_256KiB, + DN_PoolSlotSize_512KiB, + DN_PoolSlotSize_1MiB, + DN_PoolSlotSize_2MiB, + DN_PoolSlotSize_4MiB, + DN_PoolSlotSize_8MiB, + DN_PoolSlotSize_16MiB, + DN_PoolSlotSize_32MiB, + DN_PoolSlotSize_64MiB, + DN_PoolSlotSize_128MiB, + DN_PoolSlotSize_256MiB, + DN_PoolSlotSize_512MiB, + DN_PoolSlotSize_1GiB, + DN_PoolSlotSize_2GiB, + DN_PoolSlotSize_4GiB, + DN_PoolSlotSize_8GiB, + DN_PoolSlotSize_16GiB, + DN_PoolSlotSize_32GiB, + DN_PoolSlotSize_Count, +}; + +struct DN_Pool +{ + DN_Arena *arena; + DN_PoolSlot *slots[DN_PoolSlotSize_Count]; + DN_U8 align; +}; + +struct DN_NibbleFromU8Result +{ + char nibble0; + char nibble1; +}; + +enum DN_Str8EqCase +{ + DN_Str8EqCase_Sensitive, + DN_Str8EqCase_Insensitive, +}; + +enum DN_Str8IsAllType +{ + DN_Str8IsAllType_Digits, + DN_Str8IsAllType_Hex, +}; + +struct DN_Str8BSplitResult +{ + DN_Str8 lhs; + DN_Str8 rhs; +}; + +struct DN_Str8FindResult +{ + bool found; // True if string was found. If false, the subsequent fields below are not set. + DN_USize index; // Index in the buffer where the found string starts + DN_Str8 match; // Matching string in the buffer that was searched + DN_Str8 match_to_end_of_buffer; // Substring containing the found string to the end of the buffer + DN_Str8 after_match_to_end_of_buffer; // Substring starting after the found string to the end of the buffer + DN_Str8 start_to_before_match; // Substring from the start of the buffer up until the found string, not including it +}; + +enum DN_Str8FindFlag +{ + DN_Str8FindFlag_Digit = 1 << 0, // 0-9 + DN_Str8FindFlag_Whitespace = 1 << 1, // '\r', '\t', '\n', ' ' + DN_Str8FindFlag_Alphabet = 1 << 2, // A-Z, a-z + DN_Str8FindFlag_Plus = 1 << 3, // + + DN_Str8FindFlag_Minus = 1 << 4, // - + DN_Str8FindFlag_AlphaNum = DN_Str8FindFlag_Alphabet | DN_Str8FindFlag_Digit, +}; + +enum DN_Str8SplitIncludeEmptyStrings +{ + DN_Str8SplitIncludeEmptyStrings_No, + DN_Str8SplitIncludeEmptyStrings_Yes, +}; + +struct DN_Str8TruncateResult +{ + bool truncated; + DN_Str8 str8; +}; + +struct DN_Str8SplitResult +{ + DN_Str8 *data; + DN_USize count; +}; + +struct DN_Str8Link +{ + DN_Str8 string; // The string + DN_Str8Link *next; // The next string in the linked list + DN_Str8Link *prev; // The prev string in the linked list +}; + +struct DN_Str8Builder +{ + DN_Arena *arena; // Allocator to use to back the string list + DN_Str8Link *head; // First string in the linked list of strings + DN_Str8Link *tail; // Last string in the linked list of strings + DN_USize string_size; // The size in bytes necessary to construct the current string + DN_USize count; // The number of links in the linked list of strings +}; + +enum DN_Str8BuilderAdd +{ + DN_Str8BuilderAdd_Append, + DN_Str8BuilderAdd_Prepend, +}; + +typedef DN_U32 DN_AgeUnit; +enum DN_AgeUnit_ +{ + DN_AgeUnit_Ms = 1 << 0, + DN_AgeUnit_Sec = 1 << 1, + DN_AgeUnit_Min = 1 << 2, + DN_AgeUnit_Hr = 1 << 3, + DN_AgeUnit_Day = 1 << 4, + DN_AgeUnit_Week = 1 << 5, + DN_AgeUnit_Year = 1 << 6, + DN_AgeUnit_FractionalSec = 1 << 7, + DN_AgeUnit_HMS = DN_AgeUnit_Sec | DN_AgeUnit_Min | DN_AgeUnit_Hr, + DN_AgeUnit_All = DN_AgeUnit_Ms | DN_AgeUnit_HMS | DN_AgeUnit_Day | DN_AgeUnit_Week | DN_AgeUnit_Year, +}; + +enum DN_ByteCountType +{ + DN_ByteCountType_B, + DN_ByteCountType_KiB, + DN_ByteCountType_MiB, + DN_ByteCountType_GiB, + DN_ByteCountType_TiB, + DN_ByteCountType_Count, + DN_ByteCountType_Auto, +}; + +struct DN_ByteCountResult +{ + DN_ByteCountType type; + DN_Str8 suffix; // "KiB", "MiB", "GiB" .. e.t.c + DN_F64 bytes; +}; + +struct DN_FmtAppendResult +{ + DN_USize size_req; + DN_Str8 str8; + bool truncated; +}; + +#if !defined(DN_STB_SPRINTF_HEADER_ONLY) + #define STB_SPRINTF_IMPLEMENTATION + #define STB_SPRINTF_STATIC +#endif + +DN_MSVC_WARNING_PUSH +DN_MSVC_WARNING_DISABLE(4505) // Unused function warning +DN_GCC_WARNING_PUSH +DN_GCC_WARNING_DISABLE(-Wunused-function) +#include "../External/stb_sprintf.h" +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__) + +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 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) diff --git a/Source/Base/dn_base_assert.h b/Source/Base/dn_base_assert.h index 6081e0b..9b2eaa9 100644 --- a/Source/Base/dn_base_assert.h +++ b/Source/Base/dn_base_assert.h @@ -6,7 +6,7 @@ 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_), \ + DN_Str8PrintFmt(stack_trace_), \ ##__VA_ARGS__); \ DN_DebugBreak; \ } \ @@ -24,7 +24,7 @@ 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_), \ + DN_Str8PrintFmt(stack_trace_), \ ##__VA_ARGS__); \ DN_DebugBreak; \ } \ @@ -37,7 +37,7 @@ 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_), \ + DN_Str8PrintFmt(stack_trace_), \ ##__VA_ARGS__); \ DN_DebugBreak; \ } \ diff --git a/Source/Base/dn_base_compiler.h b/Source/Base/dn_base_compiler.h index 1f1bb28..6f06d72 100644 --- a/Source/Base/dn_base_compiler.h +++ b/Source/Base/dn_base_compiler.h @@ -130,7 +130,7 @@ #endif // NOTE: Type Cast ///////////////////////////////////////////////////////////////////////////////// -#define DN_CAST(val) (val) +#define DN_Cast(val) (val) // NOTE: Zero initialisation macro ///////////////////////////////////////////////////////////////// #if defined(__cplusplus) diff --git a/Source/Base/dn_base_containers.cpp b/Source/Base/dn_base_containers.cpp index 87e5ae7..97372c0 100644 --- a/Source/Base/dn_base_containers.cpp +++ b/Source/Base/dn_base_containers.cpp @@ -10,14 +10,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; @@ -66,14 +66,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); } @@ -82,13 +82,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); } @@ -101,11 +101,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); @@ -243,7 +243,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; @@ -254,7 +254,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; } @@ -268,11 +268,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; @@ -329,34 +329,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; } @@ -381,30 +381,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; @@ -517,14 +517,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; @@ -533,7 +533,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; @@ -547,18 +547,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; } @@ -640,7 +640,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; @@ -649,7 +649,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; } @@ -662,12 +662,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; @@ -691,9 +691,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; @@ -703,13 +703,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 = {}; } @@ -733,7 +733,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; } @@ -761,12 +761,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; } @@ -870,7 +870,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]; @@ -970,7 +970,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 @@ -997,7 +997,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*/) { @@ -1074,7 +1074,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; } @@ -1085,7 +1085,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; @@ -1158,16 +1158,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; } @@ -1178,15 +1178,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; } @@ -1349,12 +1349,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); @@ -1378,7 +1378,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++) { @@ -1397,7 +1397,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; } @@ -1415,7 +1415,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++) { @@ -1435,7 +1435,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; } @@ -1446,7 +1446,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; } diff --git a/Source/Base/dn_base_containers.h b/Source/Base/dn_base_containers.h index 8c3c15d..52a8941 100644 --- a/Source/Base/dn_base_containers.h +++ b/Source/Base/dn_base_containers.h @@ -176,7 +176,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 @@ -189,7 +189,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': @@ -210,13 +210,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) @@ -278,10 +278,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) @@ -296,10 +296,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) @@ -312,7 +312,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); @@ -327,7 +327,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); @@ -335,9 +335,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); @@ -347,8 +347,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); @@ -378,8 +378,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); @@ -401,7 +401,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); @@ -410,7 +410,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); diff --git a/Source/Base/dn_base_convert.cpp b/Source/Base/dn_base_convert.cpp deleted file mode 100644 index 05de7d4..0000000 --- a/Source/Base/dn_base_convert.cpp +++ /dev/null @@ -1,389 +0,0 @@ -#define DN_CONVERT_CPP - -#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; -} diff --git a/Source/Base/dn_base_convert.h b/Source/Base/dn_base_convert.h deleted file mode 100644 index ea13cbd..0000000 --- a/Source/Base/dn_base_convert.h +++ /dev/null @@ -1,97 +0,0 @@ -#if !defined(DN_BASE_CONVERT_H) -#define DN_BASE_CONVERT_H - -#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) diff --git a/Source/Base/dn_base_log.cpp b/Source/Base/dn_base_log.cpp index 2d15798..596da4d 100644 --- a/Source/Base/dn_base_log.cpp +++ b/Source/Base/dn_base_log.cpp @@ -23,9 +23,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; } @@ -35,35 +35,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 @@ -82,7 +82,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 diff --git a/Source/Base/dn_base_mem.cpp b/Source/Base/dn_base_mem.cpp index 0205857..247ec83 100644 --- a/Source/Base/dn_base_mem.cpp +++ b/Source/Base/dn_base_mem.cpp @@ -2,553 +2,3 @@ #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; -} diff --git a/Source/Base/dn_base_mem.h b/Source/Base/dn_base_mem.h index 3f25f64..571e107 100644 --- a/Source/Base/dn_base_mem.h +++ b/Source/Base/dn_base_mem.h @@ -3,244 +3,4 @@ #include "../dn_base_inc.h" -enum DN_MemCommit -{ - DN_MemCommit_No, - DN_MemCommit_Yes, -}; - -typedef DN_U32 DN_MemPage; -enum DN_MemPage_ -{ - // Exception on read/write with a page. This flag overrides the read/write - // access. - DN_MemPage_NoAccess = 1 << 0, - - DN_MemPage_Read = 1 << 1, // Only read permitted on the page. - - // Only write permitted on the page. On Windows this is not supported and - // will be promoted to read+write permissions. - DN_MemPage_Write = 1 << 2, - - DN_MemPage_ReadWrite = DN_MemPage_Read | DN_MemPage_Write, - - // Modifier used in conjunction with previous flags. Raises exception on - // first access to the page, then, the underlying protection flags are - // active. This is supported on Windows, on other OS's using this flag will - // set the OS equivalent of DN_MemPage_NoAccess. - // This flag must only be used in DN_Mem_Protect - DN_MemPage_Guard = 1 << 3, - - // If leak tracing is enabled, this flag will allow the allocation recorded - // from the reserve call to be leaked, e.g. not printed when leaks are - // dumped to the console. - DN_MemPage_AllocRecordLeakPermitted = 1 << 4, - - // If leak tracing is enabled this flag will prevent any allocation record - // from being created in the allocation table at all. If this flag is - // enabled, 'OSMemPage_AllocRecordLeakPermitted' has no effect since the - // record will never be created. - DN_MemPage_NoAllocRecordEntry = 1 << 5, - - // [INTERNAL] Do not use. All flags together do not constitute a correct - // configuration of pages. - DN_MemPage_All = DN_MemPage_NoAccess | - DN_MemPage_ReadWrite | - DN_MemPage_Guard | - DN_MemPage_AllocRecordLeakPermitted | - DN_MemPage_NoAllocRecordEntry, -}; - -#if !defined(DN_ARENA_RESERVE_SIZE) - #define DN_ARENA_RESERVE_SIZE DN_Megabytes(64) -#endif - -#if !defined(DN_ARENA_COMMIT_SIZE) - #define DN_ARENA_COMMIT_SIZE DN_Kilobytes(64) -#endif - -enum DN_Allocator -{ - DN_Allocator_Arena, - DN_Allocator_Pool, -}; - -struct DN_ArenaBlock -{ - DN_ArenaBlock *prev; - DN_U64 used; - DN_U64 commit; - DN_U64 reserve; - DN_U64 reserve_sum; -}; - -typedef uint32_t DN_ArenaFlags; - -enum DN_ArenaFlags_ -{ - DN_ArenaFlags_Nil = 0, - DN_ArenaFlags_NoGrow = 1 << 0, - DN_ArenaFlags_NoPoison = 1 << 1, - DN_ArenaFlags_NoAllocTrack = 1 << 2, - DN_ArenaFlags_AllocCanLeak = 1 << 3, - - // NOTE: Internal flags. Do not use - DN_ArenaFlags_UserBuffer = 1 << 4, - DN_ArenaFlags_MemFuncs = 1 << 5, -}; - -struct DN_ArenaInfo -{ - DN_U64 used; - DN_U64 commit; - DN_U64 reserve; - DN_U64 blocks; -}; - -struct DN_ArenaStats -{ - DN_ArenaInfo info; - DN_ArenaInfo hwm; -}; - -enum DN_ArenaMemFuncType -{ - DN_ArenaMemFuncType_Nil, - DN_ArenaMemFuncType_Basic, - DN_ArenaMemFuncType_VMem, -}; - -typedef void *(DN_ArenaMemBasicAllocFunc)(DN_USize size); -typedef void (DN_ArenaMemBasicDeallocFunc)(void *ptr); -typedef void *(DN_ArenaMemVMemReserveFunc)(DN_USize size, DN_MemCommit commit, DN_MemPage page_flags); -typedef bool (DN_ArenaMemVMemCommitFunc)(void *ptr, DN_USize size, DN_U32 page_flags); -typedef void (DN_ArenaMemVMemReleaseFunc)(void *ptr, DN_USize size); -struct DN_ArenaMemFuncs -{ - DN_ArenaMemFuncType type; - DN_ArenaMemBasicAllocFunc *basic_alloc; - DN_ArenaMemBasicDeallocFunc *basic_dealloc; - - DN_U32 vmem_page_size; - DN_ArenaMemVMemReserveFunc *vmem_reserve; - DN_ArenaMemVMemCommitFunc *vmem_commit; - DN_ArenaMemVMemReleaseFunc *vmem_release; -}; - -struct DN_Arena -{ - DN_ArenaMemFuncs mem_funcs; - DN_ArenaBlock *curr; - DN_ArenaStats stats; - DN_ArenaFlags flags; - DN_Str8 label; - DN_Arena *prev, *next; -}; - -struct DN_ArenaTempMem -{ - DN_Arena *arena; - DN_U64 used_sum; -}; - -struct DN_ArenaTempMemScope -{ - DN_ArenaTempMemScope(DN_Arena *arena); - ~DN_ArenaTempMemScope(); - DN_ArenaTempMem mem; -}; - -DN_USize const DN_ARENA_HEADER_SIZE = DN_AlignUpPowerOfTwo(sizeof(DN_Arena), 64); - -#if !defined(DN_POOL_DEFAULT_ALIGN) - #define DN_POOL_DEFAULT_ALIGN 16 -#endif - -struct DN_PoolSlot -{ - void *data; - DN_PoolSlot *next; -}; - -enum DN_PoolSlotSize -{ - DN_PoolSlotSize_32B, - DN_PoolSlotSize_64B, - DN_PoolSlotSize_128B, - DN_PoolSlotSize_256B, - DN_PoolSlotSize_512B, - DN_PoolSlotSize_1KiB, - DN_PoolSlotSize_2KiB, - DN_PoolSlotSize_4KiB, - DN_PoolSlotSize_8KiB, - DN_PoolSlotSize_16KiB, - DN_PoolSlotSize_32KiB, - DN_PoolSlotSize_64KiB, - DN_PoolSlotSize_128KiB, - DN_PoolSlotSize_256KiB, - DN_PoolSlotSize_512KiB, - DN_PoolSlotSize_1MiB, - DN_PoolSlotSize_2MiB, - DN_PoolSlotSize_4MiB, - DN_PoolSlotSize_8MiB, - DN_PoolSlotSize_16MiB, - DN_PoolSlotSize_32MiB, - DN_PoolSlotSize_64MiB, - DN_PoolSlotSize_128MiB, - DN_PoolSlotSize_256MiB, - DN_PoolSlotSize_512MiB, - DN_PoolSlotSize_1GiB, - DN_PoolSlotSize_2GiB, - DN_PoolSlotSize_4GiB, - DN_PoolSlotSize_8GiB, - DN_PoolSlotSize_16GiB, - DN_PoolSlotSize_32GiB, - DN_PoolSlotSize_Count, -}; - -struct DN_Pool -{ - DN_Arena *arena; - DN_PoolSlot *slots[DN_PoolSlotSize_Count]; - DN_U8 align; -}; - -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) diff --git a/Source/Base/dn_base_os.h b/Source/Base/dn_base_os.h index a261940..a9ee0a6 100644 --- a/Source/Base/dn_base_os.h +++ b/Source/Base/dn_base_os.h @@ -34,12 +34,12 @@ struct DN_StackTraceWalkResultIterator #if defined(DN_FREESTANDING) -#define DN_StackTrace_WalkStr8FromHeap(...) DN_STR8("N/A") +#define DN_StackTrace_WalkStr8FromHeap(...) DN_Str8Lit("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_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(...) diff --git a/Source/Base/dn_base_string.cpp b/Source/Base/dn_base_string.cpp deleted file mode 100644 index 03eda26..0000000 --- a/Source/Base/dn_base_string.cpp +++ /dev/null @@ -1,1196 +0,0 @@ -#define DN_STRING_CPP - -#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; -} diff --git a/Source/Base/dn_base_string.h b/Source/Base/dn_base_string.h deleted file mode 100644 index 3f42704..0000000 --- a/Source/Base/dn_base_string.h +++ /dev/null @@ -1,244 +0,0 @@ -#if !defined(DN_BASE_STRING_H) -#define DN_BASE_STRING_H - -#include "../dn_base_inc.h" - -#if !defined(DN_STB_SPRINTF_HEADER_ONLY) - #define STB_SPRINTF_IMPLEMENTATION - #define STB_SPRINTF_STATIC -#endif - -DN_MSVC_WARNING_PUSH -DN_MSVC_WARNING_DISABLE(4505) // Unused function warning -DN_GCC_WARNING_PUSH -DN_GCC_WARNING_DISABLE(-Wunused-function) -#include "../External/stb_sprintf.h" -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__) - -struct DN_Str8Link -{ - DN_Str8 string; // The string - DN_Str8Link *next; // The next string in the linked list - DN_Str8Link *prev; // The prev string in the linked list -}; - -struct DN_Str8BSplitResult -{ - DN_Str8 lhs; - DN_Str8 rhs; -}; - -struct DN_Str8FindResult -{ - bool found; // True if string was found. If false, the subsequent fields below are not set. - DN_USize index; // Index in the buffer where the found string starts - DN_Str8 match; // Matching string in the buffer that was searched - DN_Str8 match_to_end_of_buffer; // Substring containing the found string to the end of the buffer - DN_Str8 after_match_to_end_of_buffer; // Substring starting after the found string to the end of the buffer - DN_Str8 start_to_before_match; // Substring from the start of the buffer up until the found string, not including it -}; - -enum DN_Str8IsAll -{ - DN_Str8IsAll_Digits, - DN_Str8IsAll_Hex, -}; - -enum DN_Str8EqCase -{ - DN_Str8EqCase_Sensitive, - DN_Str8EqCase_Insensitive, -}; - -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_Str8ToU64Result -{ - bool success; - uint64_t value; -}; - -struct DN_Str8ToI64Result -{ - bool success; - int64_t value; -}; - -struct DN_Str8DotTruncateResult -{ - bool truncated; - DN_Str8 str8; -}; - -struct DN_Str8Builder -{ - DN_Arena *arena; // Allocator to use to back the string list - DN_Str8Link *head; // First string in the linked list of strings - DN_Str8Link *tail; // Last string in the linked list of strings - DN_USize string_size; // The size in bytes necessary to construct the current string - DN_USize count; // The number of links in the linked list of strings -}; - -enum DN_Str8BuilderAdd -{ - DN_Str8BuilderAdd_Append, - DN_Str8BuilderAdd_Prepend, -}; - -struct DN_Str8x64 -{ - char data[64]; - DN_USize size; -}; - -struct DN_Str8x256 -{ - char data[256]; - DN_USize size; -}; - -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) diff --git a/Source/Core/dn_core.cpp b/Source/Core/dn_core.cpp index 7ae7514..3b7c260 100644 --- a/Source/Core/dn_core.cpp +++ b/Source/Core/dn_core.cpp @@ -9,19 +9,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, @@ -30,29 +30,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; @@ -64,18 +64,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() diff --git a/Source/Core/dn_core_debug.cpp b/Source/Core/dn_core_debug.cpp index be47734..8642ce4 100644 --- a/Source/Core/dn_core_debug.cpp +++ b/Source/Core/dn_core_debug.cpp @@ -24,7 +24,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)); } } @@ -58,8 +58,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; @@ -68,14 +68,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"); } } @@ -101,9 +101,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; } @@ -119,12 +119,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; } @@ -140,7 +140,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); } @@ -167,7 +167,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); @@ -176,7 +176,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 = {}; @@ -185,10 +185,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 @@ -200,7 +200,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() @@ -229,12 +229,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 " @@ -250,10 +250,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 @@ -282,7 +282,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 " @@ -291,7 +291,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 " @@ -309,13 +309,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; @@ -333,19 +333,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 @@ -396,8 +394,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 (DN_Str8HasData(anchor->name) && 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) @@ -455,7 +453,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) @@ -474,13 +472,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); @@ -490,12 +488,12 @@ 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; } diff --git a/Source/Core/dn_core_debug.h b/Source/Core/dn_core_debug.h index fe68d3c..0c582b9 100644 --- a/Source/Core/dn_core_debug.h +++ b/Source/Core/dn_core_debug.h @@ -76,7 +76,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 @@ -84,7 +84,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); diff --git a/Source/Core/dn_core_demo.cpp b/Source/Core/dn_core_demo.cpp index 3611734..0445a18 100644 --- a/Source/Core/dn_core_demo.cpp +++ b/Source/Core/dn_core_demo.cpp @@ -39,8 +39,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. @@ -54,15 +54,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. @@ -76,7 +85,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. @@ -94,7 +103,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), @@ -135,8 +144,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 @@ -154,16 +163,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) @@ -184,11 +193,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: // @@ -219,10 +228,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 @@ -234,26 +243,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 @@ -290,8 +299,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! @@ -314,15 +323,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"); } @@ -331,16 +340,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. @@ -366,14 +366,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. @@ -382,7 +382,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); @@ -392,13 +392,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 @@ -422,15 +422,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. @@ -448,11 +440,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 @@ -473,11 +465,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 @@ -491,18 +483,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. @@ -531,12 +523,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. @@ -544,20 +536,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); @@ -566,7 +558,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 @@ -587,7 +579,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 @@ -601,7 +593,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 @@ -610,19 +602,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 (DN_Str8HasData(anchor->name)) { // ... } } - // 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 (DN_Str8HasData(anchor->name)) { // ... } } @@ -634,7 +626,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. @@ -642,14 +634,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 @@ -696,7 +688,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. // @@ -715,7 +707,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 @@ -725,7 +717,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). @@ -733,7 +725,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 @@ -741,7 +733,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 @@ -750,7 +742,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 @@ -760,33 +752,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 @@ -795,41 +787,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 @@ -840,16 +832,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. @@ -858,38 +850,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. // @@ -909,31 +905,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 // @@ -941,8 +937,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. @@ -950,11 +946,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. @@ -974,13 +970,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 @@ -991,7 +987,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 @@ -1041,21 +1037,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("%" PRIu64, 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 @@ -1079,8 +1075,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 @@ -1090,10 +1086,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: // @@ -1105,7 +1101,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); @@ -1116,7 +1112,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 @@ -1151,7 +1147,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 @@ -1164,31 +1160,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. // diff --git a/Source/Extra/dn_async.cpp b/Source/Extra/dn_async.cpp index 509c9c5..4374049 100644 --- a/Source/Extra/dn_async.cpp +++ b/Source/Extra/dn_async.cpp @@ -6,8 +6,8 @@ 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); @@ -51,7 +51,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); } } diff --git a/Source/Extra/dn_bin_pack.cpp b/Source/Extra/dn_bin_pack.cpp index 18df18f..e132790 100644 --- a/Source/Extra/dn_bin_pack.cpp +++ b/Source/Extra/dn_bin_pack.cpp @@ -6,11 +6,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; @@ -18,7 +18,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); } } } @@ -109,10 +109,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; } } @@ -121,17 +121,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; @@ -139,7 +139,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; @@ -149,9 +149,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; @@ -160,6 +160,6 @@ 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; } diff --git a/Source/Extra/dn_cgen.cpp b/Source/Extra/dn_cgen.cpp index 6dcc9b8..5f4eb18 100644 --- a/Source/Extra/dn_cgen.cpp +++ b/Source/Extra/dn_cgen.cpp @@ -16,24 +16,24 @@ */ DN_CGenMapNodeToEnum const DN_CGEN_TABLE_KEY_LIST[] = { - {DN_CGenTableKeyType_Name, DN_STR8("name")}, - {DN_CGenTableKeyType_Type, DN_STR8("type")}, + {DN_CGenTableKeyType_Name, DN_Str8Lit("name")}, + {DN_CGenTableKeyType_Type, DN_Str8Lit("type")}, }; DN_CGenMapNodeToEnum const DN_CGEN_TABLE_TYPE_LIST[] = { - {DN_CGenTableType_Data, DN_STR8("data") }, - {DN_CGenTableType_CodeGenBuiltinTypes, DN_STR8("code_gen_builtin_types")}, - {DN_CGenTableType_CodeGenStruct, DN_STR8("code_gen_struct") }, - {DN_CGenTableType_CodeGenEnum, DN_STR8("code_gen_enum") }, + {DN_CGenTableType_Data, DN_Str8Lit("data") }, + {DN_CGenTableType_CodeGenBuiltinTypes, DN_Str8Lit("code_gen_builtin_types")}, + {DN_CGenTableType_CodeGenStruct, DN_Str8Lit("code_gen_struct") }, + {DN_CGenTableType_CodeGenEnum, DN_Str8Lit("code_gen_enum") }, }; DN_CGenMapNodeToEnum const DN_CGEN_TABLE_ROW_TAG_LIST[] = { - {DN_CGenTableRowTagType_CommentDivider, DN_STR8("comment_divider")}, - {DN_CGenTableRowTagType_EmptyLine, DN_STR8("empty_line") }, + {DN_CGenTableRowTagType_CommentDivider, DN_Str8Lit("comment_divider")}, + {DN_CGenTableRowTagType_EmptyLine, DN_Str8Lit("empty_line") }, }; DN_CGenMapNodeToEnum const DN_CGEN_TABLE_ROW_TAG_COMMENT_DIVIDER_KEY_LIST[] = { - {DN_CGenTableRowTagCommentDivider_Label, DN_STR8("label")}, + {DN_CGenTableRowTagCommentDivider_Label, DN_Str8Lit("label")}, }; DN_CGenTableHeaderType const DN_CGEN_TABLE_CODE_GEN_STRUCT_HEADER_LIST[] = { @@ -88,7 +88,7 @@ static bool DN_CGen_GatherTables_(DN_CGen *cgen, DN_OSErrSink *err) DN_CGEN_TABLE_KEY_LIST, DN_ArrayCountU(DN_CGEN_TABLE_KEY_LIST), "Table specified invalid key"); - switch (DN_CAST(DN_CGenTableKeyType) key_mapping.enum_val) { + switch (DN_Cast(DN_CGenTableKeyType) key_mapping.enum_val) { case DN_CGenTableKeyType_Nil: DN_InvalidCodePath; case DN_CGenTableKeyType_Name: { @@ -101,7 +101,7 @@ static bool DN_CGen_GatherTables_(DN_CGen *cgen, DN_OSErrSink *err) DN_CGEN_TABLE_TYPE_LIST, DN_ArrayCountU(DN_CGEN_TABLE_TYPE_LIST), "Table 'type' specified invalid value"); - table->type = DN_CAST(DN_CGenTableType) table_type_validator.enum_val; + table->type = DN_Cast(DN_CGenTableType) table_type_validator.enum_val; DN_Assert(table->type <= DN_CGenTableType_Count); cgen->table_counts[table->type]++; @@ -141,14 +141,14 @@ static bool DN_CGen_GatherTables_(DN_CGen *cgen, DN_OSErrSink *err) // NOTE: Detect builtin headers and cache the index for that table ///////////////////// for (DN_USize enum_index = 0; enum_index < DN_CGenTableHeaderType_Count; enum_index++) { - DN_Str8 decl_str8 = DN_CGen_TableHeaderTypeToDeclStr8(DN_CAST(DN_CGenTableHeaderType) enum_index); - if (decl_str8 != DN_Str8_Init(header_column->string.str, header_column->string.size)) + DN_Str8 decl_str8 = DN_CGen_TableHeaderTypeToDeclStr8(DN_Cast(DN_CGenTableHeaderType) enum_index); + if (!DN_Str8Eq(decl_str8, DN_Str8FromPtr(header_column->string.str, header_column->string.size))) continue; table->column_indexes[enum_index] = column_index; break; } - MD_MapInsert(cgen->arena, &table->headers_map, MD_MapKeyStr(header_column->string), DN_CAST(void *) column_index); + MD_MapInsert(cgen->arena, &table->headers_map, MD_MapKeyStr(header_column->string), DN_Cast(void *) column_index); table->headers[column_index++].name = header_column->string; } @@ -164,7 +164,7 @@ static bool DN_CGen_GatherTables_(DN_CGen *cgen, DN_OSErrSink *err) for (DN_CGenTableHeaderType enum_val : DN_CGEN_TABLE_CODE_GEN_STRUCT_HEADER_LIST) { if (table->column_indexes[enum_val] == 0) { DN_Str8 expected_value = DN_CGen_TableHeaderTypeToDeclStr8(enum_val); - DN_CGen_LogF(MD_MessageKind_Error, table->headers_node, err, "Struct code generation table is missing column '%.*s'", DN_STR_FMT(expected_value)); + DN_CGen_LogF(MD_MessageKind_Error, table->headers_node, err, "Struct code generation table is missing column '%.*s'", DN_Str8PrintFmt(expected_value)); return false; } } @@ -174,7 +174,7 @@ static bool DN_CGen_GatherTables_(DN_CGen *cgen, DN_OSErrSink *err) for (DN_CGenTableHeaderType enum_val : DN_CGEN_TABLE_CODE_GEN_ENUM_HEADER_LIST) { if (table->column_indexes[enum_val] == 0) { DN_Str8 expected_value = DN_CGen_TableHeaderTypeToDeclStr8(enum_val); - DN_CGen_LogF(MD_MessageKind_Error, table->headers_node, err, "Enum code generation table is missing column '%.*s'", DN_STR_FMT(expected_value)); + DN_CGen_LogF(MD_MessageKind_Error, table->headers_node, err, "Enum code generation table is missing column '%.*s'", DN_Str8PrintFmt(expected_value)); return false; } } @@ -184,7 +184,7 @@ static bool DN_CGen_GatherTables_(DN_CGen *cgen, DN_OSErrSink *err) for (DN_CGenTableHeaderType enum_val : DN_CGEN_TABLE_CODE_GEN_BUILTIN_TYPES_HEADER_LIST) { if (table->column_indexes[enum_val] == 0) { DN_Str8 expected_value = DN_CGen_TableHeaderTypeToDeclStr8(enum_val); - DN_CGen_LogF(MD_MessageKind_Error, table->headers_node, err, "Enum code generation table is missing column '%.*s'", DN_STR_FMT(expected_value)); + DN_CGen_LogF(MD_MessageKind_Error, table->headers_node, err, "Enum code generation table is missing column '%.*s'", DN_Str8PrintFmt(expected_value)); return false; } } @@ -205,7 +205,7 @@ static bool DN_CGen_GatherTables_(DN_CGen *cgen, DN_OSErrSink *err) DN_ArrayCountU(DN_CGEN_TABLE_ROW_TAG_LIST), "Table specified invalid row tag"); DN_CGenTableRowTag *tag = MD_PushArray(cgen->arena, DN_CGenTableRowTag, 1); - tag->type = DN_CAST(DN_CGenTableRowTagType) row_mapping.enum_val; + tag->type = DN_Cast(DN_CGenTableRowTagType) row_mapping.enum_val; MD_QueuePush(row->first_tag, row->last_tag, tag); switch (tag->type) { @@ -217,7 +217,7 @@ static bool DN_CGen_GatherTables_(DN_CGen *cgen, DN_OSErrSink *err) DN_CGEN_TABLE_ROW_TAG_COMMENT_DIVIDER_KEY_LIST, DN_ArrayCountU(DN_CGEN_TABLE_ROW_TAG_COMMENT_DIVIDER_KEY_LIST), "Table specified invalid row tag"); - switch (DN_CAST(DN_CGenTableRowTagCommentDivider) tag_mapping.enum_val) { + switch (DN_Cast(DN_CGenTableRowTagCommentDivider) tag_mapping.enum_val) { case DN_CGenTableRowTagCommentDivider_Nil: DN_InvalidCodePath; case DN_CGenTableRowTagCommentDivider_Label: { tag->comment = tag_key->first_child->string; @@ -231,7 +231,7 @@ static bool DN_CGen_GatherTables_(DN_CGen *cgen, DN_OSErrSink *err) } for (MD_EachNode(column_node, row_node->first_child)) { - table->headers[column_index].longest_string = DN_Max(table->headers[column_index].longest_string, DN_CAST(int) column_node->string.size); + table->headers[column_index].longest_string = DN_Max(table->headers[column_index].longest_string, DN_Cast(int) column_node->string.size); row->columns[column_index].string = DN_CGen_MDToDNStr8(column_node->string); row->columns[column_index].node = column_node; column_index++; @@ -267,14 +267,14 @@ static bool DN_CGen_GatherTables_(DN_CGen *cgen, DN_OSErrSink *err) DN_CGen_LogF(MD_MessageKind_Error, column.node, err, "Code generation table binds '%.*s' to '%.*s', but the column '%.*s' does not exist in table '%.*s'\n" "NOTE: If you want '%.*s' to omit the column '%.*s' you can bind to the empty string `` to skip it, otherwise, please ensure the table '%.*s' has the column '%.*s'", - DN_STR_FMT(column.string), - DN_STR_FMT(header_type_str8), - DN_STR_FMT(column.string), - DN_STR_FMT(it.table->name), - DN_STR_FMT(it.table->name), - DN_STR_FMT(header_type_str8), - DN_STR_FMT(it.table->name), - DN_STR_FMT(header_type_str8)); + DN_Str8PrintFmt(column.string), + DN_Str8PrintFmt(header_type_str8), + DN_Str8PrintFmt(column.string), + DN_Str8PrintFmt(it.table->name), + DN_Str8PrintFmt(it.table->name), + DN_Str8PrintFmt(header_type_str8), + DN_Str8PrintFmt(it.table->name), + DN_Str8PrintFmt(header_type_str8)); } } } @@ -292,7 +292,7 @@ DN_API DN_CGen DN_CGen_FromFilesArgV(int argc, char const **argv, DN_OSErrSink * bool has_error = false; for (DN_ISize arg_index = 0; arg_index < argc; arg_index++) { - MD_String8 file_name = MD_S8CString(DN_CAST(char *) argv[arg_index]); + MD_String8 file_name = MD_S8CString(DN_Cast(char *) argv[arg_index]); MD_ParseResult parse_result = MD_ParseWholeFile(result.arena, file_name); for (MD_Message *message = parse_result.errors.first; message != 0; message = message->next) { has_error = true; @@ -310,20 +310,20 @@ DN_API DN_Str8 DN_CGen_TableHeaderTypeToDeclStr8(DN_CGenTableHeaderType type) { DN_Str8 result = {}; switch (type) { - case DN_CGenTableHeaderType_Name: result = DN_STR8("name"); break; - case DN_CGenTableHeaderType_Table: result = DN_STR8("table"); break; - case DN_CGenTableHeaderType_CppType: result = DN_STR8("cpp_type"); break; - case DN_CGenTableHeaderType_CppName: result = DN_STR8("cpp_name"); break; - case DN_CGenTableHeaderType_CppValue: result = DN_STR8("cpp_value"); break; - case DN_CGenTableHeaderType_CppIsPtr: result = DN_STR8("cpp_is_ptr"); break; - case DN_CGenTableHeaderType_CppOpEquals: result = DN_STR8("cpp_op_equals"); break; - case DN_CGenTableHeaderType_CppArraySize: result = DN_STR8("cpp_array_size"); break; - case DN_CGenTableHeaderType_CppArraySizeField: result = DN_STR8("cpp_array_size_field"); break; - case DN_CGenTableHeaderType_CppLabel: result = DN_STR8("cpp_label"); break; - case DN_CGenTableHeaderType_GenTypeInfo: result = DN_STR8("gen_type_info"); break; - case DN_CGenTableHeaderType_GenEnumCount: result = DN_STR8("gen_enum_count"); break; - case DN_CGenTableHeaderType_Count: result = DN_STR8("XX BAD ENUM VALUE XX"); break; - default: result = DN_STR8("XX INVALID ENUM VALUE XX"); break; + case DN_CGenTableHeaderType_Name: result = DN_Str8Lit("name"); break; + case DN_CGenTableHeaderType_Table: result = DN_Str8Lit("table"); break; + case DN_CGenTableHeaderType_CppType: result = DN_Str8Lit("cpp_type"); break; + case DN_CGenTableHeaderType_CppName: result = DN_Str8Lit("cpp_name"); break; + case DN_CGenTableHeaderType_CppValue: result = DN_Str8Lit("cpp_value"); break; + case DN_CGenTableHeaderType_CppIsPtr: result = DN_Str8Lit("cpp_is_ptr"); break; + case DN_CGenTableHeaderType_CppOpEquals: result = DN_Str8Lit("cpp_op_equals"); break; + case DN_CGenTableHeaderType_CppArraySize: result = DN_Str8Lit("cpp_array_size"); break; + case DN_CGenTableHeaderType_CppArraySizeField: result = DN_Str8Lit("cpp_array_size_field"); break; + case DN_CGenTableHeaderType_CppLabel: result = DN_Str8Lit("cpp_label"); break; + case DN_CGenTableHeaderType_GenTypeInfo: result = DN_Str8Lit("gen_type_info"); break; + case DN_CGenTableHeaderType_GenEnumCount: result = DN_Str8Lit("gen_enum_count"); break; + case DN_CGenTableHeaderType_Count: result = DN_Str8Lit("XX BAD ENUM VALUE XX"); break; + default: result = DN_Str8Lit("XX INVALID ENUM VALUE XX"); break; } return result; } @@ -333,32 +333,32 @@ DN_API DN_CGenMapNodeToEnum DN_CGen_MapNodeToEnumOrExit(MD_Node const *node, DN_ DN_CGenMapNodeToEnum result = {}; for (DN_USize index = 0; index < valid_keys_size; index++) { DN_CGenMapNodeToEnum const *validator = valid_keys + index; - if (DN_Str8_Init(node->string.str, node->string.size) == validator->node_string) { + if (DN_Str8Eq(DN_Str8FromPtr(node->string.str, node->string.size), validator->node_string)) { result = *validator; break; } } if (result.enum_val == 0) { - MD_CodeLoc loc = MD_CodeLocFromNode(DN_CAST(MD_Node *) node); + MD_CodeLoc loc = MD_CodeLocFromNode(DN_Cast(MD_Node *) node); DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); va_list args; va_start(args, fmt); - DN_Str8 user_msg = DN_Str8_FromFV(tmem.arena, fmt, args); + DN_Str8 user_msg = DN_Str8FromFmtVArena(tmem.arena, fmt, args); va_end(args); DN_Str8Builder builder = {}; builder.arena = tmem.arena; - DN_Str8Builder_AppendF(&builder, "%.*s: '%.*s' is not recognised, the supported values are ", DN_STR_FMT(user_msg), MD_S8VArg(node->string)); + DN_Str8BuilderAppendF(&builder, "%.*s: '%.*s' is not recognised, the supported values are ", DN_Str8PrintFmt(user_msg), MD_S8VArg(node->string)); for (DN_USize index = 0; index < valid_keys_size; index++) { DN_CGenMapNodeToEnum const *validator = valid_keys + index; - DN_Str8Builder_AppendF(&builder, DN_CAST(char *) "%s'%.*s'", index ? ", " : "", DN_STR_FMT(validator->node_string)); + DN_Str8BuilderAppendF(&builder, DN_Cast(char *) "%s'%.*s'", index ? ", " : "", DN_Str8PrintFmt(validator->node_string)); } - DN_Str8 error_msg = DN_Str8Builder_Build(&builder, tmem.arena); - MD_PrintMessageFmt(stderr, loc, MD_MessageKind_Error, DN_CAST(char *) "%.*s", DN_STR_FMT(error_msg)); - DN_OS_Exit(DN_CAST(uint32_t) - 1); + DN_Str8 error_msg = DN_Str8BuilderBuild(&builder, tmem.arena); + MD_PrintMessageFmt(stderr, loc, MD_MessageKind_Error, DN_Cast(char *) "%.*s", DN_Str8PrintFmt(error_msg)); + DN_OS_Exit(DN_Cast(uint32_t) - 1); } return result; } @@ -377,19 +377,19 @@ DN_API void DN_CGen_LogF(MD_MessageKind kind, MD_Node *node, DN_OSErrSink *err, return; DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr); - DN_Str8Builder builder = DN_Str8Builder_FromTLS(); + DN_Str8Builder builder = DN_Str8BuilderFromTLS(); MD_String8 kind_string = MD_StringFromMessageKind(kind); MD_CodeLoc loc = MD_CodeLocFromNode(node); - DN_Str8Builder_AppendF(&builder, "" MD_FmtCodeLoc " %.*s: ", MD_CodeLocVArg(loc), MD_S8VArg(kind_string)); + DN_Str8BuilderAppendF(&builder, "" MD_FmtCodeLoc " %.*s: ", MD_CodeLocVArg(loc), MD_S8VArg(kind_string)); va_list args; va_start(args, fmt); - DN_Str8Builder_AppendFV(&builder, fmt, args); + DN_Str8BuilderAppendFV(&builder, fmt, args); va_end(args); - DN_Str8 msg = DN_Str8Builder_Build(&builder, tmem.arena); - DN_OS_ErrSinkAppendF(err, DN_CAST(uint32_t) - 1, "%.*s", DN_STR_FMT(msg)); + DN_Str8 msg = DN_Str8BuilderBuild(&builder, tmem.arena); + DN_OS_ErrSinkAppendF(err, DN_Cast(uint32_t) - 1, "%.*s", DN_Str8PrintFmt(msg)); } DN_API bool DN_CGen_TableHasHeaders(DN_CGenTable const *table, DN_Str8 const *headers, DN_USize header_count, DN_OSErrSink *err) @@ -401,22 +401,22 @@ DN_API bool DN_CGen_TableHasHeaders(DN_CGenTable const *table, DN_Str8 const *he for (DN_USize index = 0; index < header_count; index++) { DN_Str8 header = headers[index]; - MD_String8 header_md = {DN_CAST(MD_u8 *) header.data, header.size}; - MD_MapSlot *slot = MD_MapLookup(DN_CAST(MD_Map *) & table->headers_map, MD_MapKeyStr(header_md)); + MD_String8 header_md = {DN_Cast(MD_u8 *) header.data, header.size}; + MD_MapSlot *slot = MD_MapLookup(DN_Cast(MD_Map *) & table->headers_map, MD_MapKeyStr(header_md)); if (!slot) { result = false; - DN_Str8Builder_AppendF(&builder, "%s%.*s", builder.count ? ", " : "", DN_STR_FMT(header)); + DN_Str8BuilderAppendF(&builder, "%s%.*s", builder.count ? ", " : "", DN_Str8PrintFmt(header)); } } if (!result) { - DN_Str8 missing_headers = DN_Str8Builder_Build(&builder, tmem.arena); + DN_Str8 missing_headers = DN_Str8BuilderBuild(&builder, tmem.arena); DN_CGen_LogF(MD_MessageKind_Error, table->headers_node, err, "Table '%.*s' is missing the header(s): %.*s", - DN_STR_FMT(table->name), - DN_STR_FMT(missing_headers)); + DN_Str8PrintFmt(table->name), + DN_Str8PrintFmt(missing_headers)); } return result; @@ -428,17 +428,17 @@ DN_API DN_CGenLookupColumnAtHeader DN_CGen_LookupColumnAtHeader(DN_CGenTable *ta if (!table || !row) return result; - MD_String8 header_md = {DN_CAST(MD_u8 *) header.data, header.size}; + MD_String8 header_md = {DN_Cast(MD_u8 *) header.data, header.size}; MD_MapSlot *slot = MD_MapLookup(&table->headers_map, MD_MapKeyStr(header_md)); if (!slot) return result; - DN_USize column_index = DN_CAST(DN_USize) slot->val; + DN_USize column_index = DN_Cast(DN_USize) slot->val; DN_Assert(column_index < table->column_count); { - DN_USize begin = DN_CAST(uintptr_t)(table->rows); - DN_USize end = DN_CAST(uintptr_t)(table->rows + table->row_count); - DN_USize ptr = DN_CAST(uintptr_t) row; + DN_USize begin = DN_Cast(uintptr_t)(table->rows); + DN_USize end = DN_Cast(uintptr_t)(table->rows + table->row_count); + DN_USize ptr = DN_Cast(uintptr_t) row; DN_AssertF(ptr >= begin && ptr <= end, "The row to lookup does not belong to the table passed in"); } @@ -466,18 +466,18 @@ DN_API bool DN_CGen_LookupNextTableInCodeGenTable(DN_CGen *cgen, DN_CGenTable *c it->cgen_table_row = cgen_table->rows + it->row_index++; if (cgen_table->type != DN_CGenTableType_CodeGenBuiltinTypes) { DN_CGenTableColumn cgen_table_column = it->cgen_table_row->columns[cgen_table->column_indexes[DN_CGenTableHeaderType_Table]]; - MD_String8 key = {DN_CAST(MD_u8 *) cgen_table_column.string.data, cgen_table_column.string.size}; + MD_String8 key = {DN_Cast(MD_u8 *) cgen_table_column.string.data, cgen_table_column.string.size}; MD_MapSlot *table_slot = MD_MapLookup(&cgen->table_map, MD_MapKeyStr(key)); if (!table_slot) { MD_CodeLoc loc = MD_CodeLocFromNode(cgen_table_column.node); MD_PrintMessageFmt(stderr, loc, MD_MessageKind_Warning, - DN_CAST(char *) "Code generation table references non-existent table '%.*s'", - DN_STR_FMT(cgen_table_column.string)); + DN_Cast(char *) "Code generation table references non-existent table '%.*s'", + DN_Str8PrintFmt(cgen_table_column.string)); return false; } - it->table = DN_CAST(DN_CGenTable *) table_slot->val; + it->table = DN_Cast(DN_CGenTable *) table_slot->val; } for (DN_USize type = 0; type < DN_CGenTableHeaderType_Count; type++) @@ -487,7 +487,7 @@ DN_API bool DN_CGen_LookupNextTableInCodeGenTable(DN_CGen *cgen, DN_CGenTable *c DN_API bool DN_CGen_WillCodeGenTypeName(DN_CGen const *cgen, DN_Str8 name) { - if (!DN_Str8_HasData(name)) + if (name.size == 0) return false; for (DN_CGenTable *table = cgen->first_table; table != 0; table = table->next) { @@ -497,7 +497,7 @@ DN_API bool DN_CGen_WillCodeGenTypeName(DN_CGen const *cgen, DN_Str8 name) for (DN_USize row_index = 0; row_index < table->row_count; row_index++) { DN_CGenTableRow const *row = table->rows + row_index; DN_CGenTableColumn const *column = row->columns + table->column_indexes[DN_CGenTableHeaderType_Name]; - if (column->string == name) + if (DN_Str8Eq(column->string, name)) return true; } } @@ -516,9 +516,9 @@ static void DN_CGen_EmitRowWhitespace_(DN_CGenTableRow const *row, DN_CppFile *c break; DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 prefix = DN_Str8_FromF(tmem.arena, "// NOTE: %.*s ", MD_S8VArg(tag->comment)); - int line_padding = DN_Max(100 - (DN_CAST(int) prefix.size + (DN_CppSpacePerIndent(cpp) * cpp->indent)), 0); - DN_CppPrint(cpp, "%.*s", DN_STR_FMT(prefix)); + DN_Str8 prefix = DN_Str8FromFmtArena(tmem.arena, "// NOTE: %.*s ", MD_S8VArg(tag->comment)); + int line_padding = DN_Max(100 - (DN_Cast(int) prefix.size + (DN_CppSpacePerIndent(cpp) * cpp->indent)), 0); + DN_CppPrint(cpp, "%.*s", DN_Str8PrintFmt(prefix)); for (int index = 0; index < line_padding; index++) DN_CppAppend(cpp, "/"); DN_CppAppend(cpp, "\n"); @@ -534,23 +534,23 @@ static void DN_CGen_EmitRowWhitespace_(DN_CGenTableRow const *row, DN_CppFile *c DN_Str8 DN_CGen_ConvertTemplatesToEmittableLiterals_(DN_Arena *arena, DN_Str8 type) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena); - DN_Str8 result = DN_Str8_TrimWhitespaceAround(type); - result = DN_Str8_Replace(result, /*find*/ DN_STR8("<"), /*replace*/ DN_STR8("_"), /*start_index*/ 0, arena, DN_Str8EqCase_Sensitive); - result = DN_Str8_Replace(result, /*find*/ DN_STR8(">"), /*replace*/ DN_STR8(""), /*start_index*/ 0, arena, DN_Str8EqCase_Sensitive); - result = DN_Str8_TrimWhitespaceAround(result); + DN_Str8 result = DN_Str8TrimWhitespaceAround(type); + result = DN_Str8Replace(result, /*find*/ DN_Str8Lit("<"), /*replace*/ DN_Str8Lit("_"), /*start_index*/ 0, arena, DN_Str8EqCase_Sensitive); + result = DN_Str8Replace(result, /*find*/ DN_Str8Lit(">"), /*replace*/ DN_Str8Lit(""), /*start_index*/ 0, arena, DN_Str8EqCase_Sensitive); + result = DN_Str8TrimWhitespaceAround(result); return result; } DN_Str8 DN_CGen_StripQualifiersOnCppType_(DN_Arena *arena, DN_Str8 type) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(arena); - DN_Str8 result = DN_Str8_TrimWhitespaceAround(type); - result = DN_Str8_Replace(result, /*find*/ DN_STR8("*"), /*replace*/ DN_STR8(""), /*start_index*/ 0, tmem.arena, DN_Str8EqCase_Sensitive); - result = DN_Str8_Replace(result, /*find*/ DN_STR8("constexpr"), /*replace*/ DN_STR8(""), /*start_index*/ 0, tmem.arena, DN_Str8EqCase_Sensitive); - result = DN_Str8_Replace(result, /*find*/ DN_STR8("const"), /*replace*/ DN_STR8(""), /*start_index*/ 0, tmem.arena, DN_Str8EqCase_Sensitive); - result = DN_Str8_Replace(result, /*find*/ DN_STR8("static"), /*replace*/ DN_STR8(""), /*start_index*/ 0, tmem.arena, DN_Str8EqCase_Sensitive); - result = DN_Str8_Replace(result, /*find*/ DN_STR8(" "), /*replace*/ DN_STR8(""), /*start_index*/ 0, arena, DN_Str8EqCase_Sensitive); - result = DN_Str8_TrimWhitespaceAround(result); + DN_Str8 result = DN_Str8TrimWhitespaceAround(type); + result = DN_Str8Replace(result, /*find*/ DN_Str8Lit("*"), /*replace*/ DN_Str8Lit(""), /*start_index*/ 0, tmem.arena, DN_Str8EqCase_Sensitive); + result = DN_Str8Replace(result, /*find*/ DN_Str8Lit("constexpr"), /*replace*/ DN_Str8Lit(""), /*start_index*/ 0, tmem.arena, DN_Str8EqCase_Sensitive); + result = DN_Str8Replace(result, /*find*/ DN_Str8Lit("const"), /*replace*/ DN_Str8Lit(""), /*start_index*/ 0, tmem.arena, DN_Str8EqCase_Sensitive); + result = DN_Str8Replace(result, /*find*/ DN_Str8Lit("static"), /*replace*/ DN_Str8Lit(""), /*start_index*/ 0, tmem.arena, DN_Str8EqCase_Sensitive); + result = DN_Str8Replace(result, /*find*/ DN_Str8Lit(" "), /*replace*/ DN_Str8Lit(""), /*start_index*/ 0, arena, DN_Str8EqCase_Sensitive); + result = DN_Str8TrimWhitespaceAround(result); return result; } @@ -558,16 +558,16 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil { if (emit & DN_CGenEmit_Prototypes) { // NOTE: Generate type info enums ////////////////////////////////////////////////////////////// - DN_CppEnumBlock(cpp, "%.*sType", DN_STR_FMT(emit_prefix)) + DN_CppEnumBlock(cpp, "%.*sType", DN_Str8PrintFmt(emit_prefix)) { - DN_CppLine(cpp, "%.*sType_Nil,", DN_STR_FMT(emit_prefix)); + DN_CppLine(cpp, "%.*sType_Nil,", DN_Str8PrintFmt(emit_prefix)); for (DN_CGenTable *table = cgen->first_table; table != 0; table = table->next) for (DN_CGenLookupTableIterator it = {}; DN_CGen_LookupNextTableInCodeGenTable(cgen, table, &it);) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); DN_Str8 enum_name = DN_CGen_ConvertTemplatesToEmittableLiterals_(tmem.arena, it.cgen_table_column[DN_CGenTableHeaderType_Name].string); - DN_CppLine(cpp, "%.*sType_%.*s,", DN_STR_FMT(emit_prefix), DN_STR_FMT(enum_name)); + DN_CppLine(cpp, "%.*sType_%.*s,", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(enum_name)); } - DN_CppLine(cpp, "%.*sType_Count,", DN_STR_FMT(emit_prefix)); + DN_CppLine(cpp, "%.*sType_Count,", DN_Str8PrintFmt(emit_prefix)); } DN_CppNewLine(cpp); @@ -593,10 +593,10 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil if (DN_CGen_WillCodeGenTypeName(cgen, find_name)) length += emit_prefix.size; - longest_type_name = DN_Max(longest_type_name, DN_CAST(int) length); + longest_type_name = DN_Max(longest_type_name, DN_Cast(int) length); } - DN_CppStructBlock(cpp, "%.*s%.*s", DN_STR_FMT(emit_prefix), DN_STR_FMT(it.cgen_table_column[DN_CGenTableHeaderType_Name].string)) + DN_CppStructBlock(cpp, "%.*s%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(it.cgen_table_column[DN_CGenTableHeaderType_Name].string)) { for (DN_USize row_index = 0; row_index < it.table->row_count; row_index++) { DN_CGenTableRow const *row = it.table->rows + row_index; @@ -610,7 +610,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); DN_Str8 array_size = {}; if (cpp_array_size.column.string.size) - array_size = DN_Str8_FromF(tmem.arena, "[%.*s]", DN_STR_FMT(cpp_array_size.column.string)); + array_size = DN_Str8FromFmtArena(tmem.arena, "[%.*s]", DN_Str8PrintFmt(cpp_array_size.column.string)); // NOTE: Check if we're referencing a code generated type. If we // are, append the `emit_prefix` @@ -618,20 +618,20 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil { DN_Str8 find_name = DN_CGen_StripQualifiersOnCppType_(tmem.arena, emit_cpp_type); if (DN_CGen_WillCodeGenTypeName(cgen, find_name)) - emit_cpp_type = DN_Str8_FromF(tmem.arena, "%.*s%.*s", DN_STR_FMT(emit_prefix), DN_STR_FMT(cpp_type.column.string)); + emit_cpp_type = DN_Str8FromFmtArena(tmem.arena, "%.*s%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(cpp_type.column.string)); } - int name_to_type_padding = 1 + longest_type_name - DN_CAST(int) emit_cpp_type.size; + int name_to_type_padding = 1 + longest_type_name - DN_Cast(int) emit_cpp_type.size; // NOTE: Emit decl ///////////////////////////////////////////////// DN_CGen_EmitRowWhitespace_(row, cpp); DN_CppLine(cpp, "%.*s%*s%.*s%.*s;", - DN_STR_FMT(emit_cpp_type), + DN_Str8PrintFmt(emit_cpp_type), name_to_type_padding, "", - DN_STR_FMT(cpp_name.column.string), - DN_STR_FMT(array_size)); + DN_Str8PrintFmt(cpp_name.column.string), + DN_Str8PrintFmt(array_size)); } } DN_CppNewLine(cpp); @@ -642,7 +642,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil case DN_CGenTableType_CodeGenEnum: { for (DN_CGenLookupTableIterator it = {}; DN_CGen_LookupNextTableInCodeGenTable(cgen, table, &it);) { - DN_CppEnumBlock(cpp, "%.*s%.*s", DN_STR_FMT(emit_prefix), DN_STR_FMT(it.cgen_table_column[DN_CGenTableHeaderType_Name].string)) + DN_CppEnumBlock(cpp, "%.*s%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(it.cgen_table_column[DN_CGenTableHeaderType_Name].string)) { DN_USize enum_count = 0; for (DN_USize row_index = 0; row_index < it.table->row_count; row_index++) { @@ -657,16 +657,16 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil if (cpp_value.column.string.size) DN_CppLine(cpp, "%.*s%.*s_%.*s = %.*s,", - DN_STR_FMT(emit_prefix), - DN_STR_FMT(it.cgen_table_column[DN_CGenTableHeaderType_Name].string), - DN_STR_FMT(cpp_name.column.string), - DN_STR_FMT(cpp_value.column.string)); + DN_Str8PrintFmt(emit_prefix), + DN_Str8PrintFmt(it.cgen_table_column[DN_CGenTableHeaderType_Name].string), + DN_Str8PrintFmt(cpp_name.column.string), + DN_Str8PrintFmt(cpp_value.column.string)); else DN_CppLine(cpp, "%.*s%.*s_%.*s = %zu,", - DN_STR_FMT(emit_prefix), - DN_STR_FMT(it.cgen_table_column[DN_CGenTableHeaderType_Name].string), - DN_STR_FMT(cpp_name.column.string), + DN_Str8PrintFmt(emit_prefix), + DN_Str8PrintFmt(it.cgen_table_column[DN_CGenTableHeaderType_Name].string), + DN_Str8PrintFmt(cpp_name.column.string), row_index); enum_count++; } @@ -675,9 +675,9 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil if (gen_enum_count_column.string.size) DN_CppLine(cpp, "%.*s%.*s_%.*s = %zu,", - DN_STR_FMT(emit_prefix), - DN_STR_FMT(it.cgen_table_column[DN_CGenTableHeaderType_Name].string), - DN_STR_FMT(gen_enum_count_column.string), + DN_Str8PrintFmt(emit_prefix), + DN_Str8PrintFmt(it.cgen_table_column[DN_CGenTableHeaderType_Name].string), + DN_Str8PrintFmt(gen_enum_count_column.string), enum_count); } DN_CppNewLine(cpp); @@ -698,7 +698,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil case DN_CGenTableType_CodeGenStruct: { for (DN_CGenLookupTableIterator it = {}; DN_CGen_LookupNextTableInCodeGenTable(cgen, table, &it);) { DN_Str8 struct_name = it.cgen_table_column[DN_CGenTableHeaderType_Name].string; - DN_CppEnumBlock(cpp, "%.*s%.*sTypeField", DN_STR_FMT(emit_prefix), DN_STR_FMT(struct_name)) + DN_CppEnumBlock(cpp, "%.*s%.*sTypeField", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(struct_name)) { for (DN_USize row_index = 0; row_index < it.table->row_count; row_index++) { DN_CGenTableRow const *row = it.table->rows + row_index; @@ -706,9 +706,9 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil if (cpp_name.column.string.size <= 0) continue; DN_CGen_EmitRowWhitespace_(row, cpp); - DN_CppLine(cpp, "%.*s%.*sTypeField_%.*s,", DN_STR_FMT(emit_prefix), DN_STR_FMT(struct_name), DN_STR_FMT(cpp_name.column.string)); + DN_CppLine(cpp, "%.*s%.*sTypeField_%.*s,", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(struct_name), DN_Str8PrintFmt(cpp_name.column.string)); } - DN_CppLine(cpp, "%.*s%.*sTypeField_Count,", DN_STR_FMT(emit_prefix), DN_STR_FMT(struct_name)); + DN_CppLine(cpp, "%.*s%.*sTypeField_Count,", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(struct_name)); } DN_CppNewLine(cpp); } @@ -723,10 +723,10 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil for (DN_CGenLookupTableIterator it = {}; DN_CGen_LookupNextTableInCodeGenTable(cgen, table, &it);) { DN_Str8 type_name = it.cgen_table_column[DN_CGenTableHeaderType_Name].string; - DN_CppStructBlock(cpp, "%.*s%.*sStr8ToEnumResult", DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name)) + DN_CppStructBlock(cpp, "%.*s%.*sStr8ToEnumResult", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name)) { DN_CppLine(cpp, "bool success;"); - DN_CppLine(cpp, "%.*s%.*s value;", DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name)); + DN_CppLine(cpp, "%.*s%.*s value;", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name)); } DN_CppNewLine(cpp); } @@ -735,8 +735,8 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil // NOTE: Type to DN_TypeField function DN_CppLine(cpp, "DN_TypeInfo const *%.*sType_Info(%.*sType type);", - DN_STR_FMT(emit_prefix), - DN_STR_FMT(emit_prefix)); + DN_Str8PrintFmt(emit_prefix), + DN_Str8PrintFmt(emit_prefix)); // NOTE: Str8 <-> Enum conversion functions for (DN_CGenTable *table = cgen->first_table; table != 0; table = table->next) { @@ -747,16 +747,16 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil DN_Str8 type_name = it.cgen_table_column[DN_CGenTableHeaderType_Name].string; DN_CppLine(cpp, "%.*s%.*sStr8ToEnumResult %.*s%.*s_NameStr8ToEnum(DN_Str8 string);", - DN_STR_FMT(emit_prefix), - DN_STR_FMT(type_name), - DN_STR_FMT(emit_prefix), - DN_STR_FMT(type_name)); + DN_Str8PrintFmt(emit_prefix), + DN_Str8PrintFmt(type_name), + DN_Str8PrintFmt(emit_prefix), + DN_Str8PrintFmt(type_name)); DN_CppLine(cpp, "%.*s%.*sStr8ToEnumResult %.*s%.*s_LabelStr8ToEnum(DN_Str8 string);", - DN_STR_FMT(emit_prefix), - DN_STR_FMT(type_name), - DN_STR_FMT(emit_prefix), - DN_STR_FMT(type_name)); + DN_Str8PrintFmt(emit_prefix), + DN_Str8PrintFmt(type_name), + DN_Str8PrintFmt(emit_prefix), + DN_Str8PrintFmt(type_name)); } } @@ -768,22 +768,22 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil for (DN_CGenLookupTableIterator it = {}; DN_CGen_LookupNextTableInCodeGenTable(cgen, table, &it);) { DN_Str8 cpp_op_equals = it.cgen_table_column[DN_CGenTableHeaderType_CppOpEquals].string; - if (cpp_op_equals != DN_STR8("true")) + if (!DN_Str8Eq(cpp_op_equals, DN_Str8Lit("true"))) continue; DN_Str8 type_name = it.cgen_table_column[DN_CGenTableHeaderType_Name].string; DN_CppLine(cpp, "bool operator==(%.*s%.*s const &lhs, %.*s%.*s const &rhs);", - DN_STR_FMT(emit_prefix), - DN_STR_FMT(type_name), - DN_STR_FMT(emit_prefix), - DN_STR_FMT(type_name)); + DN_Str8PrintFmt(emit_prefix), + DN_Str8PrintFmt(type_name), + DN_Str8PrintFmt(emit_prefix), + DN_Str8PrintFmt(type_name)); DN_CppLine(cpp, "bool operator!=(%.*s%.*s const &lhs, %.*s%.*s const &rhs);", - DN_STR_FMT(emit_prefix), - DN_STR_FMT(type_name), - DN_STR_FMT(emit_prefix), - DN_STR_FMT(type_name)); + DN_Str8PrintFmt(emit_prefix), + DN_Str8PrintFmt(type_name), + DN_Str8PrintFmt(emit_prefix), + DN_Str8PrintFmt(type_name)); } } } @@ -796,7 +796,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil continue; DN_Str8 struct_or_enum_name = it.cgen_table_column[DN_CGenTableHeaderType_Name].string; - DN_CppBlock(cpp, ";\n\n", "DN_TypeField const g_%.*s%.*s_type_fields[] =", DN_STR_FMT(emit_prefix), DN_STR_FMT(struct_or_enum_name)) + DN_CppBlock(cpp, ";\n\n", "DN_TypeField const g_%.*s%.*s_type_fields[] =", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(struct_or_enum_name)) { if (table->type == DN_CGenTableType_CodeGenStruct) { // NOTE: Construct the cpp type string first. We will prepend `emit_prefix` @@ -805,7 +805,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil // padding purposes. DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr); DN_USize longest_cpp_type_name = 0; - auto cpp_type_list = DN_SArray_Init(tmem.arena, it.table->row_count, DN_ZeroMem_Yes); + auto cpp_type_list = DN_SArray_Init(tmem.arena, it.table->row_count, DN_ZMem_Yes); for (DN_USize row_index = 0; row_index < it.table->row_count; row_index++) { DN_CGenTableRow const *row = it.table->rows + row_index; @@ -814,7 +814,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil // NOTE: CHeck the length of the string after turning it into emittable code DN_Str8 cpp_type_name = DN_CGen_StripQualifiersOnCppType_(tmem.arena, cpp_type.column.string); if (DN_CGen_WillCodeGenTypeName(cgen, cpp_type_name)) - cpp_type_name = DN_Str8_FromTLSF("%.*s%.*s", DN_STR_FMT(emit_prefix), DN_STR_FMT(cpp_type_name)); + cpp_type_name = DN_Str8FromTLSF("%.*s%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(cpp_type_name)); DN_Str8 cpp_type_name_no_templates = DN_CGen_ConvertTemplatesToEmittableLiterals_(tmem.arena, cpp_type_name); longest_cpp_type_name = DN_Max(longest_cpp_type_name, cpp_type_name_no_templates.size); @@ -832,11 +832,11 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil DN_CGenLookupColumnAtHeader cpp_array_size_field = DN_CGen_LookupColumnAtHeader(it.table, it.cgen_table_column[DN_CGenTableHeaderType_CppArraySizeField].string, row); DN_CGenLookupColumnAtHeader cpp_label = DN_CGen_LookupColumnAtHeader(it.table, it.cgen_table_column[DN_CGenTableHeaderType_CppLabel].string, row); - bool cpp_is_ptr_b32 = cpp_is_ptr.column.string == DN_STR8("true"); - DN_Str8 cpp_array_size_str8 = DN_Str8_HasData(cpp_array_size.column.string) ? cpp_array_size.column.string : DN_STR8("0"); + bool cpp_is_ptr_b32 = DN_Str8Eq(cpp_is_ptr.column.string, DN_Str8Lit("true")); + DN_Str8 cpp_array_size_str8 = cpp_array_size.column.string.size ? cpp_array_size.column.string : DN_Str8Lit("0"); DN_CGenTableColumn struct_name = it.cgen_table_row->columns[table->column_indexes[DN_CGenTableHeaderType_Name]]; - DN_Str8 cpp_array_size_field_str8 = DN_STR8("NULL"); + DN_Str8 cpp_array_size_field_str8 = DN_Str8Lit("NULL"); if (cpp_array_size_field.column.string.size) { // TODO(doyle): Check that array_size_field references a valid field in the table // NOTE: We use a raw index for the reference because the struct might @@ -845,13 +845,13 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil for (DN_USize sub_row_index = 0; sub_row_index < it.table->row_count; sub_row_index++) { DN_CGenTableRow const *sub_row = it.table->rows + sub_row_index; DN_CGenTableColumn sub_cpp_name = sub_row->columns[cpp_name.index]; - if (sub_cpp_name.string == cpp_array_size_field.column.string) + if (DN_Str8Eq(sub_cpp_name.string, cpp_array_size_field.column.string)) index_the_field_references = sub_row_index; } cpp_array_size_field_str8 = - DN_Str8_FromTLSF("&g_%.*s%.*s_type_fields[%zu]", - DN_STR_FMT(emit_prefix), - DN_STR_FMT(struct_name.string), + DN_Str8FromTLSF("&g_%.*s%.*s_type_fields[%zu]", + DN_Str8PrintFmt(emit_prefix), + DN_Str8PrintFmt(struct_name.string), index_the_field_references); } @@ -862,7 +862,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil DN_USize cpp_name_padding = 1 + it.table->headers[cpp_name.index].longest_string - cpp_name.column.string.size; DN_USize cpp_type_padding = 1 + longest_cpp_type_name - cpp_type_name.size; - DN_Str8 cpp_type_enum = DN_Str8_FromTLSF("%.*sType_%.*s", DN_STR_FMT(emit_prefix), DN_STR_FMT(orig_cpp_type_no_templates)); + DN_Str8 cpp_type_enum = DN_Str8FromTLSF("%.*sType_%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(orig_cpp_type_no_templates)); DN_USize cpp_type_enum_padding = cpp_type_padding + (orig_cpp_type.size - cpp_type_name.size); DN_Str8 cpp_label_str8 = cpp_name.column.string; @@ -872,83 +872,83 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil cpp_label_str8_padding = 1 + it.table->headers[cpp_label.index].longest_string - cpp_label.column.string.size; } - DN_Str8Builder builder = DN_Str8Builder_FromArena(tmem.arena); + DN_Str8Builder builder = DN_Str8BuilderFromArena(tmem.arena); // NOTE: row - DN_Str8Builder_AppendF(&builder, "{%2d, ", row_index); + DN_Str8BuilderAppendF(&builder, "{%2d, ", row_index); // NOTE: name - DN_Str8Builder_AppendF(&builder, - "DN_STR8(\"%.*s\"),%*s", - DN_STR_FMT(cpp_name.column.string), + DN_Str8BuilderAppendF(&builder, + "DN_Str8Lit(\"%.*s\"),%*s", + DN_Str8PrintFmt(cpp_name.column.string), cpp_name_padding, ""); // NOTE: label - DN_Str8Builder_AppendF(&builder, - "DN_STR8(\"%.*s\"),%*s", - DN_STR_FMT(cpp_label_str8), + DN_Str8BuilderAppendF(&builder, + "DN_Str8Lit(\"%.*s\"),%*s", + DN_Str8PrintFmt(cpp_label_str8), cpp_label_str8_padding, ""); // NOTE: value - DN_Str8Builder_AppendF(&builder, + DN_Str8BuilderAppendF(&builder, "/*value*/ 0, "); // NOTE: offsetof(a, b) - DN_Str8Builder_AppendF(&builder, + DN_Str8BuilderAppendF(&builder, "offsetof(%.*s%.*s, %.*s),%*s", - DN_STR_FMT(emit_prefix), - DN_STR_FMT(struct_or_enum_name), - DN_STR_FMT(cpp_name.column.string), + DN_Str8PrintFmt(emit_prefix), + DN_Str8PrintFmt(struct_or_enum_name), + DN_Str8PrintFmt(cpp_name.column.string), cpp_name_padding, ""); // NOTE: sizeof(a->b) - DN_Str8Builder_AppendF(&builder, + DN_Str8BuilderAppendF(&builder, "sizeof(((%.*s%.*s*)0)->%.*s),%*s", - DN_STR_FMT(emit_prefix), - DN_STR_FMT(struct_or_enum_name), - DN_STR_FMT(cpp_name.column.string), + DN_Str8PrintFmt(emit_prefix), + DN_Str8PrintFmt(struct_or_enum_name), + DN_Str8PrintFmt(cpp_name.column.string), cpp_name_padding, ""); // NOTE: alignof(a) - if (cpp_type_name == DN_STR8("void")) { - DN_Str8 proxy_type = DN_STR8("char"); + if (DN_Str8Eq(cpp_type_name, DN_Str8Lit("void"))) { + DN_Str8 proxy_type = DN_Str8Lit("char"); DN_USize proxy_type_padding = 1 + longest_cpp_type_name - proxy_type.size; - DN_Str8Builder_AppendF(&builder, "alignof(%.*s),%*s", DN_STR_FMT(proxy_type), proxy_type_padding, ""); + DN_Str8BuilderAppendF(&builder, "alignof(%.*s),%*s", DN_Str8PrintFmt(proxy_type), proxy_type_padding, ""); } else { - DN_Str8Builder_AppendF(&builder, + DN_Str8BuilderAppendF(&builder, "alignof(%.*s),%*s", - DN_STR_FMT(cpp_type_name), + DN_Str8PrintFmt(cpp_type_name), cpp_type_padding, ""); } // NOTE: Type string - DN_Str8Builder_AppendF(&builder, - "DN_STR8(\"%.*s\"),%*s", - DN_STR_FMT(cpp_type_name), + DN_Str8BuilderAppendF(&builder, + "DN_Str8Lit(\"%.*s\"),%*s", + DN_Str8PrintFmt(cpp_type_name), cpp_type_padding, ""); // NOTE: Type as enum - DN_Str8Builder_AppendF(&builder, + DN_Str8BuilderAppendF(&builder, "%.*s,%*s", - DN_STR_FMT(cpp_type_enum), + DN_Str8PrintFmt(cpp_type_enum), cpp_type_enum_padding, ""); - DN_Str8Builder_AppendF(&builder, + DN_Str8BuilderAppendF(&builder, "/*is_pointer*/ %s,%s /*array_size*/ %.*s, /*array_size_field*/ %.*s},", cpp_is_ptr_b32 ? "true" : "false", cpp_is_ptr_b32 ? " " : "", - DN_STR_FMT(cpp_array_size_str8), - DN_STR_FMT(cpp_array_size_field_str8)); + DN_Str8PrintFmt(cpp_array_size_str8), + DN_Str8PrintFmt(cpp_array_size_field_str8)); - DN_Str8 line = DN_Str8Builder_Build(&builder, tmem.arena); - DN_CppLine(cpp, "%.*s", DN_STR_FMT(line)); + DN_Str8 line = DN_Str8BuilderBuild(&builder, tmem.arena); + DN_CppLine(cpp, "%.*s", DN_Str8PrintFmt(line)); } } else { DN_Assert(table->type == DN_CGenTableType_CodeGenEnum); @@ -962,8 +962,8 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr); DN_USize cpp_name_padding = 1 + it.table->headers[cpp_name.index].longest_string - cpp_name.column.string.size; - DN_Str8 cpp_value_str8 = DN_Str8_HasData(cpp_value.column.string) ? cpp_value.column.string : DN_Str8_FromTLSF("%zu", row_index); - DN_Str8 cpp_type_enum = DN_Str8_FromTLSF("%.*sType_%.*s", DN_STR_FMT(emit_prefix), DN_STR_FMT(struct_or_enum_name)); + DN_Str8 cpp_value_str8 = cpp_value.column.string.size ? cpp_value.column.string : DN_Str8FromTLSF("%zu", row_index); + DN_Str8 cpp_type_enum = DN_Str8FromTLSF("%.*sType_%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(struct_or_enum_name)); DN_Str8 cpp_label_str8 = cpp_name.column.string; DN_USize cpp_label_str8_padding = cpp_name_padding; @@ -972,51 +972,51 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil cpp_label_str8_padding = 1 + it.table->headers[cpp_label.index].longest_string - cpp_label.column.string.size; } - DN_Str8Builder builder = DN_Str8Builder_FromTLS(); + DN_Str8Builder builder = DN_Str8BuilderFromTLS(); // NOTE: row - DN_Str8Builder_AppendF(&builder, "{%2d, ", row_index); + DN_Str8BuilderAppendF(&builder, "{%2d, ", row_index); // NOTE: name - DN_Str8Builder_AppendF(&builder, - "DN_STR8(\"%.*s\"),%*s", - DN_STR_FMT(cpp_name.column.string), + DN_Str8BuilderAppendF(&builder, + "DN_Str8Lit(\"%.*s\"),%*s", + DN_Str8PrintFmt(cpp_name.column.string), cpp_name_padding, ""); // NOTE: label - DN_Str8Builder_AppendF(&builder, - "DN_STR8(\"%.*s\"),%*s", - DN_STR_FMT(cpp_label_str8), + DN_Str8BuilderAppendF(&builder, + "DN_Str8Lit(\"%.*s\"),%*s", + DN_Str8PrintFmt(cpp_label_str8), cpp_label_str8_padding, ""); // NOTE: value - DN_Str8Builder_AppendF(&builder, "/*value*/ %.*s, ", DN_STR_FMT(cpp_value_str8)); + DN_Str8BuilderAppendF(&builder, "/*value*/ %.*s, ", DN_Str8PrintFmt(cpp_value_str8)); // NOTE: offsetof(a, b) - DN_Str8Builder_AppendF(&builder, "/*offsetof*/ 0, "); + DN_Str8BuilderAppendF(&builder, "/*offsetof*/ 0, "); // NOTE: sizeof(a->b) - DN_Str8Builder_AppendF(&builder, + DN_Str8BuilderAppendF(&builder, "sizeof(%.*s%.*s), ", - DN_STR_FMT(emit_prefix), - DN_STR_FMT(struct_or_enum_name)); + DN_Str8PrintFmt(emit_prefix), + DN_Str8PrintFmt(struct_or_enum_name)); // NOTE: alignof(a->b) - DN_Str8Builder_AppendF(&builder, "alignof(%.*s%.*s), ", DN_STR_FMT(emit_prefix), DN_STR_FMT(struct_or_enum_name)); + DN_Str8BuilderAppendF(&builder, "alignof(%.*s%.*s), ", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(struct_or_enum_name)); // TODO: Type string - DN_Str8Builder_AppendF(&builder, "DN_STR8(\"\"), "); + DN_Str8BuilderAppendF(&builder, "DN_Str8Lit(\"\"), "); // NOTE: Type as enum - DN_Str8Builder_AppendF(&builder, "%.*s, ", DN_STR_FMT(cpp_type_enum)); + DN_Str8BuilderAppendF(&builder, "%.*s, ", DN_Str8PrintFmt(cpp_type_enum)); - DN_Str8Builder_AppendF(&builder, "/*is_pointer*/ false, "); - DN_Str8Builder_AppendF(&builder, "/*array_size*/ 0, "); - DN_Str8Builder_AppendF(&builder, "/*array_size_field*/ NULL},"); + DN_Str8BuilderAppendF(&builder, "/*is_pointer*/ false, "); + DN_Str8BuilderAppendF(&builder, "/*array_size*/ 0, "); + DN_Str8BuilderAppendF(&builder, "/*array_size_field*/ NULL},"); - DN_Str8 line = DN_Str8Builder_BuildFromTLS(&builder); - DN_CppLine(cpp, "%.*s", DN_STR_FMT(line)); + DN_Str8 line = DN_Str8BuilderBuildFromTLS(&builder); + DN_CppLine(cpp, "%.*s", DN_Str8PrintFmt(line)); } } } @@ -1029,15 +1029,15 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); DN_Str8 type_name = it.cgen_table_column[DN_CGenTableHeaderType_Name].string; if (DN_CGen_WillCodeGenTypeName(cgen, type_name)) - type_name = DN_Str8_FromF(tmem.arena, "%.*s%.*s", DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name)); + type_name = DN_Str8FromFmtArena(tmem.arena, "%.*s%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name)); - longest_name_across_all_tables = DN_Max(longest_name_across_all_tables, DN_CAST(int) type_name.size); + longest_name_across_all_tables = DN_Max(longest_name_across_all_tables, DN_Cast(int) type_name.size); } } - DN_CppBlock(cpp, ";\n\n", "DN_TypeInfo const g_%.*stypes[] =", DN_STR_FMT(emit_prefix)) + DN_CppBlock(cpp, ";\n\n", "DN_TypeInfo const g_%.*stypes[] =", DN_Str8PrintFmt(emit_prefix)) { - DN_CppLine(cpp, "{DN_STR8(\"\"),%*sDN_TypeKind_Nil, 0, /*fields*/ NULL, /*count*/ 0},", 1 + longest_name_across_all_tables, ""); + DN_CppLine(cpp, "{DN_Str8Lit(\"\"),%*sDN_TypeKind_Nil, 0, /*fields*/ NULL, /*count*/ 0},", 1 + longest_name_across_all_tables, ""); DN_USize longest_type_name = 0; for (DN_CGenTable *table = cgen->first_table; table != 0; table = table->next) { @@ -1045,7 +1045,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); DN_Str8 type_name = it.cgen_table_column[DN_CGenTableHeaderType_Name].string; if (DN_CGen_WillCodeGenTypeName(cgen, type_name)) - type_name = DN_Str8_FromF(tmem.arena, "%.*s%.*s", DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name)); + type_name = DN_Str8FromFmtArena(tmem.arena, "%.*s%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name)); longest_type_name = DN_Max(longest_type_name, type_name.size); } } @@ -1055,89 +1055,78 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr); DN_Str8 type_name = it.cgen_table_column[DN_CGenTableHeaderType_Name].string; if (DN_CGen_WillCodeGenTypeName(cgen, type_name)) - type_name = DN_Str8_FromTLSF("%.*s%.*s", DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name)); + type_name = DN_Str8FromTLSF("%.*s%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name)); - int name_padding = 1 + longest_name_across_all_tables - DN_CAST(int) type_name.size; + int name_padding = 1 + longest_name_across_all_tables - DN_Cast(int) type_name.size; DN_Str8 type_info_kind = {}; char const *type_info_kind_padding = ""; if (table->type == DN_CGenTableType_CodeGenEnum) { - type_info_kind = DN_STR8("DN_TypeKind_Enum"); + type_info_kind = DN_Str8Lit("DN_TypeKind_Enum"); type_info_kind_padding = " "; } else if (table->type == DN_CGenTableType_CodeGenStruct) { - type_info_kind = DN_STR8("DN_TypeKind_Struct"); + type_info_kind = DN_Str8Lit("DN_TypeKind_Struct"); } else { DN_Assert(table->type == DN_CGenTableType_CodeGenBuiltinTypes); - type_info_kind = DN_STR8("DN_TypeKind_Basic"); + type_info_kind = DN_Str8Lit("DN_TypeKind_Basic"); type_info_kind_padding = " "; } - DN_Str8 fields_count = {}; - if (table->type == DN_CGenTableType_CodeGenBuiltinTypes) { - fields_count = DN_STR8("0"); - } else { - DN_Assert(table->type == DN_CGenTableType_CodeGenStruct || table->type == DN_CGenTableType_CodeGenEnum); - int fields_count_int = 0; - for (DN_USize row_index = 0; row_index < it.table->row_count; row_index++) { - DN_CGenTableRow const *row = it.table->rows + row_index; - DN_CGenLookupColumnAtHeader cpp_name = DN_CGen_LookupColumnAtHeader(it.table, it.cgen_table_column[DN_CGenTableHeaderType_CppName].string, row); - fields_count_int += DN_Str8_HasData(cpp_name.column.string); - } - fields_count = DN_Str8_FromTLSF("%d", fields_count_int); - } - - DN_Str8 fields = DN_STR8("NULL"); + DN_Str8 fields = DN_Str8Lit("NULL"); int fields_padding = 1; if (table->type != DN_CGenTableType_CodeGenBuiltinTypes) { fields_padding = name_padding; - fields = DN_Str8_FromF(tmem.arena, "g_%.*s_type_fields", DN_STR_FMT(type_name)); + fields = DN_Str8FromFmtArena(tmem.arena, "g_%.*s_type_fields", DN_Str8PrintFmt(type_name)); } - DN_Str8Builder builder = DN_Str8Builder_FromTLS(); + DN_Str8 fields_count = DN_Str8Lit("0"); + if (!DN_Str8Eq(fields, DN_Str8Lit("NULL"))) + fields_count = DN_Str8FromTLSF("sizeof(%.*s)/sizeof(%.*s[0])", DN_Str8PrintFmt(fields), DN_Str8PrintFmt(fields)); + DN_Str8Builder builder = DN_Str8BuilderFromTLS(); // NOTE: name - DN_Str8Builder_AppendF(&builder, "{DN_STR8(\"%.*s\"),%*s", DN_STR_FMT(type_name), name_padding, ""); + DN_Str8BuilderAppendF(&builder, "{DN_Str8Lit(\"%.*s\"),%*s", DN_Str8PrintFmt(type_name), name_padding, ""); // NOTE: DN_TypeKind_{Nil|Basic|Enum|Struct} - DN_Str8Builder_AppendF(&builder, "%.*s,%s", DN_STR_FMT(type_info_kind), type_info_kind_padding); + DN_Str8BuilderAppendF(&builder, "%.*s,%s", DN_Str8PrintFmt(type_info_kind), type_info_kind_padding); // NOTE: sizeof(T) - if (type_name == DN_STR8("void")) - DN_Str8Builder_AppendF(&builder, "0,%*s", name_padding, ""); + if (DN_Str8Eq(type_name, DN_Str8Lit("void"))) + DN_Str8BuilderAppendF(&builder, "0,%*s", name_padding, ""); else - DN_Str8Builder_AppendF(&builder, "sizeof(%.*s),%*s", DN_STR_FMT(type_name), name_padding, ""); + DN_Str8BuilderAppendF(&builder, "sizeof(%.*s),%*s", DN_Str8PrintFmt(type_name), name_padding, ""); // NOTE: Pointer to DN_TypeField[] - DN_Str8Builder_AppendF(&builder, "/*fields*/ %.*s,%*s", DN_STR_FMT(fields), fields_padding, ""); + DN_Str8BuilderAppendF(&builder, "/*fields*/ %.*s,%*s", DN_Str8PrintFmt(fields), fields_padding, ""); // NOTE: DN_TypeField length - DN_Str8Builder_AppendF(&builder, "/*count*/ %.*s},", DN_STR_FMT(fields_count)); + DN_Str8BuilderAppendF(&builder, "/*count*/ %.*s},", DN_Str8PrintFmt(fields_count)); - DN_Str8 line = DN_Str8Builder_BuildFromTLS(&builder); - DN_CppLine(cpp, "%.*s", DN_STR_FMT(line)); + DN_Str8 line = DN_Str8BuilderBuildFromTLS(&builder); + DN_CppLine(cpp, "%.*s", DN_Str8PrintFmt(line)); } } } // NOTE: Type to DN_TypeField function - DN_CppFuncBlock(cpp, "DN_TypeInfo const *%.*sType_Info(%.*sType type)", DN_STR_FMT(emit_prefix), DN_STR_FMT(emit_prefix)) + DN_CppFuncBlock(cpp, "DN_TypeInfo const *%.*sType_Info(%.*sType type)", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(emit_prefix)) { - DN_CppLine(cpp, "DN_TypeInfo const *result = g_%.*stypes + 0;", DN_STR_FMT(emit_prefix)); + DN_CppLine(cpp, "DN_TypeInfo const *result = g_%.*stypes + 0;", DN_Str8PrintFmt(emit_prefix)); DN_CppSwitchBlock(cpp, "type") { - DN_CppLine(cpp, "case %.*sType_Nil: break;", DN_STR_FMT(emit_prefix)); - DN_CppLine(cpp, "case %.*sType_Count: break;", DN_STR_FMT(emit_prefix)); + DN_CppLine(cpp, "case %.*sType_Nil: break;", DN_Str8PrintFmt(emit_prefix)); + DN_CppLine(cpp, "case %.*sType_Count: break;", DN_Str8PrintFmt(emit_prefix)); DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); for (DN_CGenTable *table = cgen->first_table; table != 0; table = table->next) { for (DN_CGenLookupTableIterator it = {}; DN_CGen_LookupNextTableInCodeGenTable(cgen, table, &it);) { DN_Str8 enum_name = DN_CGen_ConvertTemplatesToEmittableLiterals_(tmem.arena, it.cgen_table_column[DN_CGenTableHeaderType_Name].string); - DN_Str8 full_enum_name = DN_Str8_FromF(tmem.arena, "%.*sType_%.*s", DN_STR_FMT(emit_prefix), DN_STR_FMT(enum_name)); + DN_Str8 full_enum_name = DN_Str8FromFmtArena(tmem.arena, "%.*sType_%.*s", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(enum_name)); // NOTE: Builtin types don't have type info - DN_Str8 full_variable_name = DN_Str8_FromF(tmem.arena, "g_%.*s%.*s_type_fields", DN_STR_FMT(emit_prefix), DN_STR_FMT(enum_name)); + DN_Str8 full_variable_name = DN_Str8FromFmtArena(tmem.arena, "g_%.*s%.*s_type_fields", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(enum_name)); if (it.cgen_table->type == DN_CGenTableType_CodeGenBuiltinTypes) - full_variable_name = DN_STR8("nullptr"); + full_variable_name = DN_Str8Lit("nullptr"); - DN_CppLine(cpp, "case %.*s: result = g_%.*stypes + %.*s; break;", DN_STR_FMT(full_enum_name), DN_STR_FMT(emit_prefix), DN_STR_FMT(full_enum_name)); + DN_CppLine(cpp, "case %.*s: result = g_%.*stypes + %.*s; break;", DN_Str8PrintFmt(full_enum_name), DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(full_enum_name)); } } } @@ -1152,18 +1141,18 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil for (DN_CGenLookupTableIterator it = {}; DN_CGen_LookupNextTableInCodeGenTable(cgen, table, &it);) { DN_Str8 type_name = it.cgen_table_column[DN_CGenTableHeaderType_Name].string; - DN_CppFuncBlock(cpp, "%.*s%.*sStr8ToEnumResult %.*s%.*s_NameStr8ToEnum(DN_Str8 string)", DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name), DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name)) + DN_CppFuncBlock(cpp, "%.*s%.*sStr8ToEnumResult %.*s%.*s_NameStr8ToEnum(DN_Str8 string)", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name), DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name)) { - DN_CppLine(cpp, "%.*s%.*sStr8ToEnumResult result = {};", DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name)); - DN_CppForBlock(cpp, "DN_USize index = 0; !result.success && index < DN_ArrayCountU(g_%.*s%.*s_type_fields); index++", DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name)) + DN_CppLine(cpp, "%.*s%.*sStr8ToEnumResult result = {};", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name)); + DN_CppForBlock(cpp, "DN_USize index = 0; !result.success && index < DN_ArrayCountU(g_%.*s%.*s_type_fields); index++", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name)) { DN_CppIfChain(cpp) { - DN_CppLine(cpp, "DN_TypeField field = g_%.*s%.*s_type_fields[index];", DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name)); - DN_CppIfOrElseIfBlock(cpp, "DN_Str8_EqInsensitive(string, field.name)") + DN_CppLine(cpp, "DN_TypeField field = g_%.*s%.*s_type_fields[index];", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name)); + DN_CppIfOrElseIfBlock(cpp, "DN_Str8EqInsensitive(string, field.name)") { DN_CppLine(cpp, "result.success = true;"); - DN_CppLine(cpp, "result.value = (%.*s%.*s)index;", DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name)); + DN_CppLine(cpp, "result.value = (%.*s%.*s)index;", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name)); } } } @@ -1171,18 +1160,18 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil } DN_CppNewLine(cpp); - DN_CppFuncBlock(cpp, "%.*s%.*sStr8ToEnumResult %.*s%.*s_LabelStr8ToEnum(DN_Str8 string)", DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name), DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name)) + DN_CppFuncBlock(cpp, "%.*s%.*sStr8ToEnumResult %.*s%.*s_LabelStr8ToEnum(DN_Str8 string)", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name), DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name)) { - DN_CppLine(cpp, "%.*s%.*sStr8ToEnumResult result = {};", DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name)); - DN_CppForBlock(cpp, "DN_USize index = 0; !result.success && index < DN_ArrayCountU(g_%.*s%.*s_type_fields); index++", DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name)) + DN_CppLine(cpp, "%.*s%.*sStr8ToEnumResult result = {};", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name)); + DN_CppForBlock(cpp, "DN_USize index = 0; !result.success && index < DN_ArrayCountU(g_%.*s%.*s_type_fields); index++", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name)) { DN_CppIfChain(cpp) { - DN_CppLine(cpp, "DN_TypeField field = g_%.*s%.*s_type_fields[index];", DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name)); - DN_CppIfOrElseIfBlock(cpp, "DN_Str8_EqInsensitive(string, field.label)") + DN_CppLine(cpp, "DN_TypeField field = g_%.*s%.*s_type_fields[index];", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name)); + DN_CppIfOrElseIfBlock(cpp, "DN_Str8EqInsensitive(string, field.label)") { DN_CppLine(cpp, "result.success = true;"); - DN_CppLine(cpp, "result.value = (%.*s%.*s)index;", DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name)); + DN_CppLine(cpp, "result.value = (%.*s%.*s)index;", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name)); } } } @@ -1199,11 +1188,11 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil for (DN_CGenLookupTableIterator it = {}; DN_CGen_LookupNextTableInCodeGenTable(cgen, table, &it);) { DN_Str8 cpp_op_equals = it.cgen_table_column[DN_CGenTableHeaderType_CppOpEquals].string; - if (cpp_op_equals != DN_STR8("true")) + if (!DN_Str8Eq(cpp_op_equals, DN_Str8Lit("true"))) continue; DN_Str8 type_name = it.cgen_table_column[DN_CGenTableHeaderType_Name].string; - DN_CppFuncBlock(cpp, "bool operator==(%.*s%.*s const &lhs, %.*s%.*s const &rhs)", DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name), DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name)) + DN_CppFuncBlock(cpp, "bool operator==(%.*s%.*s const &lhs, %.*s%.*s const &rhs)", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name), DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name)) { for (DN_USize row_index = 0; row_index < it.table->row_count; row_index++) { DN_CGenTableRow const *row = it.table->rows + row_index; @@ -1214,13 +1203,13 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil // TODO(doyle): Check if we're an integral type or not to double check if we // can use memcmp or operator== - if (DN_Str8_HasData(cpp_array_size_field.column.string)) { + if (cpp_array_size_field.column.string.size) { DN_CppIfChain(cpp) { DN_CppIfOrElseIfBlock(cpp, "lhs.%.*s != rhs.%.*s", - DN_STR_FMT(cpp_array_size_field.column.string), - DN_STR_FMT(cpp_array_size_field.column.string)) + DN_Str8PrintFmt(cpp_array_size_field.column.string), + DN_Str8PrintFmt(cpp_array_size_field.column.string)) { DN_CppLine(cpp, "return false;"); } @@ -1229,32 +1218,32 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil { DN_CppIfOrElseIfBlock(cpp, "DN_Memcmp(lhs.%.*s, rhs.%.*s, lhs.%.*s) != 0", - DN_STR_FMT(cpp_name.column.string), - DN_STR_FMT(cpp_name.column.string), - DN_STR_FMT(cpp_array_size_field.column.string)) + DN_Str8PrintFmt(cpp_name.column.string), + DN_Str8PrintFmt(cpp_name.column.string), + DN_Str8PrintFmt(cpp_array_size_field.column.string)) { DN_CppLine(cpp, "return false;"); } } - } else if (DN_Str8_HasData(cpp_array_size.column.string)) { + } else if (cpp_array_size.column.string.size) { DN_CppIfChain(cpp) { DN_CppIfOrElseIfBlock(cpp, "DN_Memcmp(lhs.%.*s, rhs.%.*s, %.*s) != 0", - DN_STR_FMT(cpp_name.column.string), - DN_STR_FMT(cpp_name.column.string), - DN_STR_FMT(cpp_array_size.column.string)) + DN_Str8PrintFmt(cpp_name.column.string), + DN_Str8PrintFmt(cpp_name.column.string), + DN_Str8PrintFmt(cpp_array_size.column.string)) { DN_CppLine(cpp, "return false;"); } } - } else if (cpp_is_ptr.column.string == DN_STR8("true")) { + } else if (DN_Str8Eq(cpp_is_ptr.column.string, DN_Str8Lit("true"))) { DN_CppIfChain(cpp) { DN_CppIfOrElseIfBlock(cpp, "*lhs.%.*s != *rhs.%.*s", - DN_STR_FMT(cpp_name.column.string), - DN_STR_FMT(cpp_name.column.string)) + DN_Str8PrintFmt(cpp_name.column.string), + DN_Str8PrintFmt(cpp_name.column.string)) { DN_CppLine(cpp, "return false;"); } @@ -1264,8 +1253,8 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil { DN_CppIfOrElseIfBlock(cpp, "lhs.%.*s != rhs.%.*s", - DN_STR_FMT(cpp_name.column.string), - DN_STR_FMT(cpp_name.column.string)) + DN_Str8PrintFmt(cpp_name.column.string), + DN_Str8PrintFmt(cpp_name.column.string)) { DN_CppLine(cpp, "return false;"); } @@ -1276,7 +1265,7 @@ DN_API void DN_CGen_EmitCodeForTables(DN_CGen *cgen, DN_CGenEmit emit, DN_CppFil } DN_CppNewLine(cpp); - DN_CppFuncBlock(cpp, "bool operator!=(%.*s%.*s const &lhs, %.*s%.*s const &rhs)", DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name), DN_STR_FMT(emit_prefix), DN_STR_FMT(type_name)) + DN_CppFuncBlock(cpp, "bool operator!=(%.*s%.*s const &lhs, %.*s%.*s const &rhs)", DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name), DN_Str8PrintFmt(emit_prefix), DN_Str8PrintFmt(type_name)) { DN_CppLine(cpp, "bool result = !(lhs == rhs);"); DN_CppLine(cpp, "return result;"); diff --git a/Source/Extra/dn_cgen.h b/Source/Extra/dn_cgen.h index 0b1e7c7..988d994 100644 --- a/Source/Extra/dn_cgen.h +++ b/Source/Extra/dn_cgen.h @@ -180,10 +180,10 @@ enum DN_CGenEmit DN_CGenEmit_Implementation = 1 << 1, }; -#define DN_CGen_MDToDNStr8(str8) DN_Str8_Init((str8).str, (str8).size) +#define DN_CGen_MDToDNStr8(str8) DN_Str8FromPtr((str8).str, (str8).size) #define DN_CGen_DNToMDStr8(str8) \ { \ - DN_CAST(MD_u8 *) \ + DN_Cast(MD_u8 *) \ (str8).data, \ (str8).size \ } diff --git a/Source/Extra/dn_csv.cpp b/Source/Extra/dn_csv.cpp index 208353c..b8652bb 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_Str8_HasData(tokeniser->string)) { + if (DN_CSV_TokeniserValid(tokeniser) && DN_Str8HasData(tokeniser->string)) { // 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_Str8_HasData(tokeniser->string)) { + if (!DN_Str8HasData(tokeniser->string)) { tokeniser->bad = true; return result; } @@ -111,8 +111,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; } @@ -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_Str8_HasData(fields[result])) + if (!DN_CSV_TokeniserValid(tokeniser) || !DN_Str8HasData(fields[result])) break; } @@ -177,11 +177,11 @@ static void DN_CSV_PackU64(DN_CSVPack *pack, DN_CSVSerialise serialise, DN_U64 * { 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_Str8ToU64Result to_u64 = DN_Str8ToU64(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); } } @@ -189,11 +189,11 @@ static void DN_CSV_PackI64(DN_CSVPack *pack, DN_CSVSerialise serialise, DN_I64 * { 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_Str8ToI64Result to_i64 = DN_Str8ToI64(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); } } @@ -250,9 +250,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_Str8FromStr8(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)); } } @@ -263,7 +263,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); } } @@ -281,7 +281,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; } diff --git a/Source/Extra/dn_hash.cpp b/Source/Extra/dn_hash.cpp index 737a2a1..6dea8c8 100644 --- a/Source/Extra/dn_hash.cpp +++ b/Source/Extra/dn_hash.cpp @@ -21,7 +21,7 @@ // 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; @@ -35,7 +35,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; diff --git a/Source/Extra/dn_hash.h b/Source/Extra/dn_hash.h index c6bb4a8..919cd66 100644 --- a/Source/Extra/dn_hash.h +++ b/Source/Extra/dn_hash.h @@ -40,6 +40,6 @@ 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) diff --git a/Source/Extra/dn_helpers.cpp b/Source/Extra/dn_helpers.cpp index 8569bc4..8997e17 100644 --- a/Source/Extra/dn_helpers.cpp +++ b/Source/Extra/dn_helpers.cpp @@ -106,7 +106,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; } @@ -142,18 +142,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++; @@ -164,7 +164,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); } @@ -178,22 +178,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) @@ -239,136 +239,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; -} diff --git a/Source/Extra/dn_helpers.h b/Source/Extra/dn_helpers.h index beada28..98fe624 100644 --- a/Source/Extra/dn_helpers.h +++ b/Source/Extra/dn_helpers.h @@ -95,42 +95,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); @@ -173,41 +137,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/Extra/dn_json.cpp b/Source/Extra/dn_json.cpp index b0aebe8..d9175d2 100644 --- a/Source/Extra/dn_json.cpp +++ b/Source/Extra/dn_json.cpp @@ -7,8 +7,8 @@ void *DN_JSON_ArenaAllocFunc(void *user_data, size_t count) if (!user_data) return result; - DN_Arena *arena = DN_CAST(DN_Arena*)user_data; - result = DN_Arena_Alloc(arena, count, alignof(json_value_s), DN_ZeroMem_No); + DN_Arena *arena = DN_Cast(DN_Arena*)user_data; + result = DN_ArenaAlloc(arena, count, alignof(json_value_s), DN_ZMem_No); return result; } @@ -30,9 +30,9 @@ char const *DN_JSON_TypeEnumCString(json_type_e type, size_t *size) bool DN_JSON_String8Cmp(json_string_s const *lhs, DN_Str8 key) { bool result = false; - if (lhs && DN_Str8_HasData(key)) { - DN_Str8 lhs_string = DN_Str8_Init(lhs->string, lhs->string_size); - result = DN_Str8_Eq(lhs_string, key); + if (lhs && key.size) { + DN_Str8 lhs_string = DN_Str8FromPtr(lhs->string, lhs->string_size); + result = DN_Str8Eq(lhs_string, key); } return result; } @@ -42,7 +42,7 @@ DN_JSONIt DN_JSON_LoadFileToIt(DN_Arena *arena, DN_Str8 json) { json_parse_result_s parse_result = {}; json_value_ex_s *ex_value = - DN_CAST(json_value_ex_s *) json_parse_ex(json.data, + DN_Cast(json_value_ex_s *) json_parse_ex(json.data, json.size, json_parse_flags_allow_location_information, DN_JSON_ArenaAllocFunc, @@ -124,13 +124,13 @@ json_value_s *DN_JSON_ItPushCurrValue(DN_JSONIt *it) return result; if (curr->type == DN_JSON_ItEntryTypeObjElement) { - json_object_element_s *element = DN_CAST(json_object_element_s *) curr->value; + json_object_element_s *element = DN_Cast(json_object_element_s *) curr->value; result = element->value; } else if (curr->type == DN_JSON_ItEntryTypeArrayElement) { - json_array_element_s *element = DN_CAST(json_array_element_s *) curr->value; + json_array_element_s *element = DN_Cast(json_array_element_s *) curr->value; result = element->value; } else { - result = DN_CAST(json_value_s *) curr->value; + result = DN_Cast(json_value_s *) curr->value; } if (result->type == json_type_array) { @@ -155,18 +155,18 @@ bool DN_JSON_ItNext(DN_JSONIt *it) json_object_element_s *obj_element = nullptr; json_array_element_s *array_element = nullptr; if (curr->type == DN_JSON_ItEntryTypeObj) { - auto *obj = DN_CAST(json_object_s *) curr->value; + auto *obj = DN_Cast(json_object_s *) curr->value; obj_element = obj->start; } else if (curr->type == DN_JSON_ItEntryTypeObjElement) { - auto *element = DN_CAST(json_object_element_s *) curr->value; + auto *element = DN_Cast(json_object_element_s *) curr->value; obj_element = element->next; DN_JSON_ItPop(it); } else if (curr->type == DN_JSON_ItEntryTypeArray) { - auto *value = DN_CAST(json_value_s *) curr->value; + auto *value = DN_Cast(json_value_s *) curr->value; auto *array = json_value_as_array(value); array_element = array->start; } else if (curr->type == DN_JSON_ItEntryTypeArrayElement) { - auto *element = DN_CAST(json_array_element_s *) curr->value; + auto *element = DN_Cast(json_array_element_s *) curr->value; array_element = element->next; DN_JSON_ItPop(it); } else { @@ -201,17 +201,17 @@ json_value_s *DN_JSON_ItCurrValue(DN_JSONIt *it) return result; if (curr->type == DN_JSON_ItEntryTypeObjElement) { - auto *element = DN_CAST(json_object_element_s *)curr->value; + auto *element = DN_Cast(json_object_element_s *)curr->value; result = element->value; } else if (curr->type == DN_JSON_ItEntryTypeArrayElement) { - auto *element = DN_CAST(json_array_element_s *)curr->value; + auto *element = DN_Cast(json_array_element_s *)curr->value; result = element->value; } else if (curr->type == DN_JSON_ItEntryTypeString || curr->type == DN_JSON_ItEntryTypeNumber || curr->type == DN_JSON_ItEntryTypeObj || curr->type == DN_JSON_ItEntryTypeArray) { - result = DN_CAST(json_value_s *)curr->value; + result = DN_Cast(json_value_s *)curr->value; } return result; @@ -221,7 +221,7 @@ json_object_element_s *DN_JSON_ItCurrObjElement(DN_JSONIt *it) { DN_JSONItEntry *curr = DN_JSON_ItCurr(it); auto *result = (curr && curr->type == DN_JSON_ItEntryTypeObjElement) - ? DN_CAST(json_object_element_s *) curr->value + ? DN_Cast(json_object_element_s *) curr->value : nullptr; return result; } @@ -291,7 +291,7 @@ DN_Str8 DN_JSON_ItKey(DN_JSONIt *it) json_object_element_s *curr = DN_JSON_ItCurrObjElement(it); DN_Str8 result = {}; if (curr) { - result.data = DN_CAST(char *)curr->name->string; + result.data = DN_Cast(char *)curr->name->string; result.size = curr->name->string_size; } return result; @@ -364,7 +364,7 @@ DN_Str8 DN_JSON_ItValueToString(DN_JSONIt *it) { DN_Str8 result = {}; if (json_string_s *curr = DN_JSON_ItValueIsString(it)) - result = DN_Str8_Init(curr->string, curr->string_size); + result = DN_Str8FromPtr(curr->string, curr->string_size); return result; } @@ -372,7 +372,7 @@ int64_t DN_JSON_ItValueToI64(DN_JSONIt *it) { int64_t result = {}; if (json_number_s *curr = DN_JSON_ItValueIsNumber(it)) - result = DN_Str8_ToI64(DN_Str8_Init(curr->number, curr->number_size), 0 /*separator*/).value; + result = DN_I64FromStr8(DN_Str8FromPtr(curr->number, curr->number_size), 0 /*separator*/).value; return result; } @@ -380,7 +380,7 @@ uint64_t DN_JSON_ItValueToU64(DN_JSONIt *it) { uint64_t result = {}; if (json_number_s *curr = DN_JSON_ItValueIsNumber(it)) - result = DN_Str8_ToU64(DN_Str8_Init(curr->number, curr->number_size), 0 /*separator*/).value; + result = DN_U64FromStr8(DN_Str8FromPtr(curr->number, curr->number_size), 0 /*separator*/).value; return result; } @@ -402,27 +402,27 @@ void DN_JSON_ItErrorUnknownKeyValue_(DN_JSONIt *it, DN_CallSite call_site) return; size_t value_type_size = 0; - char const *value_type = DN_JSON_TypeEnumCString(DN_CAST(json_type_e)curr->value->type, &value_type_size); + char const *value_type = DN_JSON_TypeEnumCString(DN_Cast(json_type_e)curr->value->type, &value_type_size); json_string_s const *key = curr->name; if (it->flags & json_parse_flags_allow_location_information) { - json_string_ex_s const *info = DN_CAST(json_string_ex_s const *)key; + json_string_ex_s const *info = DN_Cast(json_string_ex_s const *)key; DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Warning), call_site, "Unknown key-value pair in object [loc=%zu:%zu, key=%.*s, value=%.*s]", info->line_no, info->row_no, - DN_CAST(int) key->string_size, + DN_Cast(int) key->string_size, key->string, - DN_CAST(int) value_type_size, + DN_Cast(int) value_type_size, value_type); } else { DN_LOG_EmitFromType(DN_LOG_MakeU32LogTypeParam(DN_LOGType_Warning), call_site, "Unknown key-value pair in object [key=%.*s, value=%.*s]", - DN_CAST(int) key->string_size, + DN_Cast(int) key->string_size, key->string, - DN_CAST(int) value_type_size, + DN_Cast(int) value_type_size, value_type); } } diff --git a/Source/Extra/dn_math.cpp b/Source/Extra/dn_math.cpp index 3929065..6936924 100644 --- a/Source/Extra/dn_math.cpp +++ b/Source/Extra/dn_math.cpp @@ -1200,15 +1200,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; } diff --git a/Source/Extra/dn_net2_curl.cpp b/Source/Extra/dn_net2_curl.cpp index 76b623c..cb9045b 100644 --- a/Source/Extra/dn_net2_curl.cpp +++ b/Source/Extra/dn_net2_curl.cpp @@ -24,24 +24,24 @@ static DN_NET2Response DN_NET2_WaitForAnyResponse(DN_NET2Core *net, DN_Arena *ar // NOTE: Fill in the result DN_NET2ResponseInternal const *response = &request->response; - result.request = {DN_CAST(DN_U64) request}; + result.request = {DN_Cast(DN_U64) request}; result.success = response->status != DN_NET2RequestStatus_Error; result.ws_type = response->ws_type; result.http_status = response->http_status; - result.body = DN_Str8Builder_Build(&response->body, arena); + result.body = DN_Str8BuilderBuild(&response->body, arena); if (response->error.size) - result.error = DN_Str8_FromStr8(arena, response->error); + result.error = DN_Str8FromStr8Arena(arena, response->error); // NOTE: Deallocate the memory used in the request - DN_Arena_PopTo(&request->arena, request->start_response_arena_pos); - request->response.body = DN_Str8Builder_FromArena(&request->arena); + DN_ArenaPopTo(&request->arena, request->start_response_arena_pos); + request->response.body = DN_Str8BuilderFromArena(&request->arena); // NOTE: For websocket requests, notify the NET thread we've read data from it and it can go // back to polling the socket for more data if (request->type == DN_NET2RequestType_WS && request->response.status != DN_NET2RequestStatus_Error) { DN_NET2RingEvent event = {}; event.type = DN_NET2RingEventType_ReceivedWSReceipt; - event.request = {DN_CAST(DN_U64)request}; + event.request = {DN_Cast(DN_U64)request}; for (DN_OS_MutexScope(&net->ring_mutex)) DN_Ring_WriteStruct(&net->ring, &event); curl_multi_wakeup(net->curlm); @@ -55,7 +55,7 @@ static DN_NET2Response DN_NET2_WaitForResponse(DN_NET2Core *net, DN_NET2Request { DN_NET2Response result = {}; if (request.handle != 0) { - DN_NET2RequestInternal *request_ptr = DN_CAST(DN_NET2RequestInternal *) request.handle; + DN_NET2RequestInternal *request_ptr = DN_Cast(DN_NET2RequestInternal *) request.handle; DN_OSSemaphoreWaitResult wait = DN_OS_SemaphoreWait(&request_ptr->completion_sem, timeout_ms); if (wait == DN_OSSemaphoreWaitResult_Success) { // NOTE: Fill in the result @@ -64,19 +64,19 @@ static DN_NET2Response DN_NET2_WaitForResponse(DN_NET2Core *net, DN_NET2Request result.success = response->status != DN_NET2RequestStatus_Error; result.ws_type = response->ws_type; result.http_status = response->http_status; - result.body = DN_Str8Builder_Build(&response->body, arena); + result.body = DN_Str8BuilderBuild(&response->body, arena); if (response->error.size) - result.error = DN_Str8_FromStr8(arena, response->error); + result.error = DN_Str8FromStr8Arena(arena, response->error); // NOTE: Deallocate the memory used in the request - DN_Arena_PopTo(&request_ptr->arena, request_ptr->start_response_arena_pos); - request_ptr->response.body = DN_Str8Builder_FromArena(&request_ptr->arena); + DN_ArenaPopTo(&request_ptr->arena, request_ptr->start_response_arena_pos); + request_ptr->response.body = DN_Str8BuilderFromArena(&request_ptr->arena); // NOTE: Decrement the global completion tracking semaphore (this is so that if you waited on // the net object's semaphore, you don't get a phantom wakeup because this function already // consumed it). DN_OSSemaphoreWaitResult net_wait_result = DN_OS_SemaphoreWait(&net->completion_sem, 0 /*timeout_ms*/); - DN_AssertF(net_wait_result == DN_OSSemaphoreWaitResult_Success, "Wait result was: %zu", DN_CAST(DN_USize)net_wait_result); + DN_AssertF(net_wait_result == DN_OSSemaphoreWaitResult_Success, "Wait result was: %zu", DN_Cast(DN_USize)net_wait_result); // NOTE: Remove the request from the done list for (DN_OS_MutexScope(&net->free_or_done_mutex)) { @@ -119,18 +119,18 @@ static void DN_NET2_DeinitRequest(DN_NET2Core *net, DN_NET2Request *request) static DN_USize DN_NET2_HTTPCallback_(char *payload, DN_USize size, DN_USize count, void *user_data) { - auto *request = DN_CAST(DN_NET2RequestInternal *) user_data; + auto *request = DN_Cast(DN_NET2RequestInternal *) user_data; DN_USize result = 0; DN_USize payload_size = size * count; - if (DN_Str8Builder_AppendBytesCopy(&request->response.body, payload, payload_size)) + if (DN_Str8BuilderAppendBytesCopy(&request->response.body, payload, payload_size)) result = payload_size; return result; } static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread) { - DN_NET2Core *net = DN_CAST(DN_NET2Core *) thread->user_context; - DN_OS_ThreadSetName(DN_Str8_Init(net->curl_thread.name.data, net->curl_thread.name.size)); + DN_NET2Core *net = DN_Cast(DN_NET2Core *) thread->user_context; + DN_OS_ThreadSetName(DN_Str8FromPtr(net->curl_thread.name.data, net->curl_thread.name.size)); for (;;) { DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr); @@ -146,7 +146,7 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread) case DN_NET2RingEventType_Nil: dequeue_ring = false; break; case DN_NET2RingEventType_DoHTTP: { - DN_NET2RequestInternal *request = DN_CAST(DN_NET2RequestInternal *)event.request.handle; + DN_NET2RequestInternal *request = DN_Cast(DN_NET2RequestInternal *)event.request.handle; DN_Assert(request->response.status != DN_NET2RequestStatus_Error); switch (request->type) { case DN_NET2RequestType_Nil: { @@ -156,7 +156,7 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread) case DN_NET2RequestType_HTTP: { DN_Assert(request->response.status == DN_NET2RequestStatus_Nil); - DN_NET2CurlConn *conn = DN_CAST(DN_NET2CurlConn *) request->context; + DN_NET2CurlConn *conn = DN_Cast(DN_NET2CurlConn *) request->context; CURLMcode multi_add = curl_multi_add_handle(net->curlm, conn->curl); DN_Assert(multi_add == CURLM_OK); DN_Assert(request->next == nullptr); @@ -172,7 +172,7 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread) DN_Assert(request->next == nullptr); DN_Assert(request->prev == nullptr); if (request->response.status == DN_NET2RequestStatus_Nil) { - DN_NET2CurlConn *conn = DN_CAST(DN_NET2CurlConn *) request->context; + DN_NET2CurlConn *conn = DN_Cast(DN_NET2CurlConn *) request->context; CURLMcode multi_add = curl_multi_add_handle(net->curlm, conn->curl); DN_Assert(multi_add == CURLM_OK); DN_DLList_Append(net->http_list, request); // Open the WS connection @@ -187,7 +187,7 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread) DN_Str8 payload = {}; for (DN_OS_MutexScope(&net->ring_mutex)) { DN_Assert(DN_Ring_HasData(&net->ring, event.send_ws_payload_size)); - payload = DN_Str8_Alloc(tmem.arena, event.send_ws_payload_size, DN_ZeroMem_No); + payload = DN_Str8FromArena(tmem.arena, event.send_ws_payload_size, DN_ZMem_No); DN_Ring_Read(&net->ring, payload.data, payload.size); } @@ -201,11 +201,11 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread) case DN_NET2WSType_Pong: curlws_flag = CURLWS_PONG; break; } - DN_NET2RequestInternal *request = DN_CAST(DN_NET2RequestInternal *) event.request.handle; + DN_NET2RequestInternal *request = DN_Cast(DN_NET2RequestInternal *) event.request.handle; DN_Assert(request->type == DN_NET2RequestType_WS); DN_Assert(request->response.status == DN_NET2RequestStatus_HTTPReceived || request->response.status == DN_NET2RequestStatus_WSReceived); - DN_NET2CurlConn *conn = DN_CAST(DN_NET2CurlConn *) request->context; + DN_NET2CurlConn *conn = DN_Cast(DN_NET2CurlConn *) request->context; DN_USize sent = 0; CURLcode send_result = curl_ws_send(conn->curl, payload.data, payload.size, &sent, 0, curlws_flag); DN_AssertF(send_result == CURLE_OK, "Failed to send: %s", curl_easy_strerror(send_result)); @@ -213,7 +213,7 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread) } break; case DN_NET2RingEventType_ReceivedWSReceipt: { - DN_NET2RequestInternal *request = DN_CAST(DN_NET2RequestInternal *) event.request.handle; + DN_NET2RequestInternal *request = DN_Cast(DN_NET2RequestInternal *) event.request.handle; DN_Assert(request->type == DN_NET2RequestType_WS); DN_Assert(request->response.status == DN_NET2RequestStatus_WSReceived || request->response.status == DN_NET2RequestStatus_HTTPReceived); @@ -224,13 +224,13 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread) case DN_NET2RingEventType_DeinitRequest: { if (event.request.handle != 0) { - DN_NET2RequestInternal *request = DN_CAST(DN_NET2RequestInternal *) event.request.handle; + DN_NET2RequestInternal *request = DN_Cast(DN_NET2RequestInternal *) event.request.handle; request->response = {}; - DN_Arena_Clear(&request->arena); + DN_ArenaClear(&request->arena); DN_OS_SemaphoreDeinit(&request->completion_sem); - DN_NET2CurlConn *conn = DN_CAST(DN_NET2CurlConn *) request->context; + DN_NET2CurlConn *conn = DN_Cast(DN_NET2CurlConn *) request->context; curl_multi_remove_handle(net->curlm, conn->curl); curl_easy_reset(conn->curl); curl_slist_free_all(conn->curl_slist); @@ -255,10 +255,10 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread) if (msg) { // NOTE: Get request handle DN_NET2RequestInternal *request = nullptr; - curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, DN_CAST(void **) & request); + curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, DN_Cast(void **) & request); DN_Assert(request); - DN_NET2CurlConn *conn = DN_CAST(DN_NET2CurlConn *)request->context; + DN_NET2CurlConn *conn = DN_Cast(DN_NET2CurlConn *)request->context; DN_Assert(conn->curl == msg->easy_handle); if (msg->data.result == CURLE_OK) { @@ -267,14 +267,14 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread) if (get_result == CURLE_OK) { request->response.status = DN_NET2RequestStatus_HTTPReceived; } else { - request->response.error = DN_Str8_FromF(&request->arena, "Failed to get HTTP response status (CURL %d): %s", msg->data.result, curl_easy_strerror(get_result)); + request->response.error = DN_Str8FromFmtArena(&request->arena, "Failed to get HTTP response status (CURL %d): %s", msg->data.result, curl_easy_strerror(get_result)); request->response.status = DN_NET2RequestStatus_Error; } } else { request->response.status = DN_NET2RequestStatus_Error; - request->response.error = DN_Str8_FromF(&request->arena, + request->response.error = DN_Str8FromFmtArena(&request->arena, "Net request to '%.*s' failed (CURL %d): %s", - DN_STR_FMT(request->url), + DN_Str8PrintFmt(request->url), msg->data.result, curl_easy_strerror(msg->data.result)); } @@ -309,7 +309,7 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread) const curl_ws_frame *meta = nullptr; size_t bytes_read_this_frame = {}; - DN_NET2CurlConn *conn = DN_CAST(DN_NET2CurlConn *) request->context; + DN_NET2CurlConn *conn = DN_Cast(DN_NET2CurlConn *) request->context; for (;;) { // NOTE: Determine WS payload size received DN_USize bytes_read = 0; @@ -318,10 +318,10 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread) break; // NOTE: Allocate and read - DN_Str8 buffer = DN_Str8_Alloc(&request->arena, meta->bytesleft, DN_ZeroMem_No); + DN_Str8 buffer = DN_Str8FromArena(&request->arena, meta->bytesleft, DN_ZMem_No); receive_result = curl_ws_recv(conn->curl, buffer.data, buffer.size, &buffer.size, &meta); bytes_read_this_frame += buffer.size; - DN_Str8Builder_AppendRef(&request->response.body, buffer); + DN_Str8BuilderAppendRef(&request->response.body, buffer); if (meta->flags & CURLWS_TEXT) request->response.ws_type = DN_NET2WSType_Text; @@ -364,9 +364,9 @@ static int32_t DN_NET2_ThreadEntryPoint_(DN_OSThread *thread) request->response.status = DN_NET2RequestStatus_WSReceived; if (receive_result != CURLE_OK) { request->response.status = DN_NET2RequestStatus_Error; - request->response.error = DN_Str8_FromF(&request->arena, + request->response.error = DN_Str8FromFmtArena(&request->arena, "Websocket failed to receive data for '%.*s' (CURL %d): %s", - DN_STR_FMT(request->url), + DN_Str8PrintFmt(request->url), receive_result, curl_easy_strerror(receive_result)); } @@ -385,25 +385,25 @@ static void DN_NET2_Init(DN_NET2Core *net, char *ring_base, DN_USize ring_size, { net->base = base; net->base_size = base_size; - net->arena = DN_Arena_FromBuffer(net->base, net->base_size, DN_ArenaFlags_Nil); + net->arena = DN_ArenaFromBuffer(net->base, net->base_size, DN_ArenaFlags_Nil); net->ring.base = ring_base; net->ring.size = ring_size; net->ring_mutex = DN_OS_MutexInit(); net->completion_sem = DN_OS_SemaphoreInit(0); net->free_or_done_mutex = DN_OS_MutexInit(); - net->curlm = DN_CAST(CURLM *)curl_multi_init(); + net->curlm = DN_Cast(CURLM *)curl_multi_init(); DN_DLList_InitArena(net->free_list, DN_NET2RequestInternal, &net->arena); DN_DLList_InitArena(net->http_list, DN_NET2RequestInternal, &net->arena); DN_DLList_InitArena(net->ws_list, DN_NET2RequestInternal, &net->arena); DN_DLList_InitArena(net->done_list, DN_NET2RequestInternal, &net->arena); - DN_IStr8_AppendF(&net->curl_thread.name, "NET (CURL)"); + DN_FmtAppend(net->curl_thread.name.data, &net->curl_thread.name.size, sizeof(net->curl_thread.name.data), "NET (CURL)"); DN_OS_ThreadInit(&net->curl_thread, DN_NET2_ThreadEntryPoint_, net); } static void DN_NET2_SetupCurlRequest_(DN_NET2RequestInternal *request) { - DN_NET2CurlConn *conn = DN_CAST(DN_NET2CurlConn *) request->context; + DN_NET2CurlConn *conn = DN_Cast(DN_NET2CurlConn *) request->context; CURL *curl = conn->curl; curl_easy_setopt(curl, CURLOPT_PRIVATE, request); @@ -430,13 +430,13 @@ static void DN_NET2_SetupCurlRequest_(DN_NET2RequestInternal *request) } break; case DN_NET2RequestType_HTTP: { - request->method = DN_Str8_TrimWhitespaceAround(request->method); - DN_Str8 const GET = DN_STR8("GET"); - DN_Str8 const POST = DN_STR8("POST"); + request->method = DN_Str8TrimWhitespaceAround(request->method); + DN_Str8 const GET = DN_Str8Lit("GET"); + DN_Str8 const POST = DN_Str8Lit("POST"); - if (DN_Str8_EqInsensitive(request->method, GET)) { + if (DN_Str8EqInsensitive(request->method, GET)) { curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); - } else if (DN_Str8_EqInsensitive(request->method, POST)) { + } else if (DN_Str8EqInsensitive(request->method, POST)) { curl_easy_setopt(curl, CURLOPT_POST, 1); if (request->args.payload.size > DN_Gigabytes(2)) curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, request->args.payload.size); @@ -451,7 +451,7 @@ static void DN_NET2_SetupCurlRequest_(DN_NET2RequestInternal *request) // NOTE: Handle basic auth if (request->args.flags & DN_NET2DoHTTPFlags_BasicAuth) { - if (DN_Str8_HasData(request->args.username) && DN_Str8_HasData(request->args.password)) { + if (request->args.username.size && request->args.password.size) { DN_Assert(request->args.username.data[request->args.username.size] == 0); DN_Assert(request->args.password.data[request->args.password.size] == 0); curl_easy_setopt(curl, CURLOPT_USERNAME, request->args.username.data); @@ -470,42 +470,42 @@ static DN_NET2Request DN_NET2_DoRequest_(DN_NET2Core *net, DN_Str8 url, DN_Str8 DN_DLList_Dequeue(net->free_list, request); if (!request) { - request = DN_Arena_New(&net->arena, DN_NET2RequestInternal, DN_ZeroMem_Yes); + request = DN_ArenaNew(&net->arena, DN_NET2RequestInternal, DN_ZMem_Yes); DN_NET2CurlConn *conn = new (request->context) DN_NET2CurlConn; - conn->curl = DN_CAST(CURL *)curl_easy_init(); + conn->curl = DN_Cast(CURL *)curl_easy_init(); } // NOTE: Setup request DN_NET2Request result = {}; if (request) { - result.handle = DN_CAST(DN_U64) request; + result.handle = DN_Cast(DN_U64) request; if (!request->arena.curr) - request->arena = DN_Arena_FromVMem(DN_Megabytes(1), DN_Kilobytes(1), DN_ArenaFlags_Nil); + request->arena = DN_ArenaFromVMem(DN_Megabytes(1), DN_Kilobytes(1), DN_ArenaFlags_Nil); request->type = type; request->gen = DN_Max(request->gen + 1, 1); - request->url = DN_Str8_FromStr8(&request->arena, url); - request->method = DN_Str8_FromStr8(&request->arena, method); + request->url = DN_Str8FromStr8Arena(&request->arena, url); + request->method = DN_Str8FromStr8Arena(&request->arena, method); if (args) { request->args.flags = args->flags; - request->args.username = DN_Str8_FromStr8(&request->arena, args->username); - request->args.password = DN_Str8_FromStr8(&request->arena, args->password); + request->args.username = DN_Str8FromStr8Arena(&request->arena, args->username); + request->args.password = DN_Str8FromStr8Arena(&request->arena, args->password); if (type == DN_NET2RequestType_HTTP) - request->args.payload = DN_Str8_FromStr8(&request->arena, args->payload); + request->args.payload = DN_Str8FromStr8Arena(&request->arena, args->payload); - request->args.headers = DN_Arena_NewArray(&request->arena, DN_Str8, args->headers_size, DN_ZeroMem_No); + request->args.headers = DN_ArenaNewArray(&request->arena, DN_Str8, args->headers_size, DN_ZMem_No); DN_Assert(request->args.headers); if (request->args.headers) { for (DN_ForItSize(it, DN_Str8, args->headers, args->headers_size)) - request->args.headers[it.index] = DN_Str8_FromStr8(&request->arena, *it.data); + request->args.headers[it.index] = DN_Str8FromStr8Arena(&request->arena, *it.data); request->args.headers_size = args->headers_size; } } - request->response.body = DN_Str8Builder_FromArena(&request->arena); + request->response.body = DN_Str8BuilderFromArena(&request->arena); request->completion_sem = DN_OS_SemaphoreInit(0); - request->start_response_arena_pos = DN_Arena_Pos(&request->arena); + request->start_response_arena_pos = DN_ArenaPos(&request->arena); DN_NET2_SetupCurlRequest_(request); @@ -530,7 +530,7 @@ static DN_NET2Request DN_NET2_DoHTTP(DN_NET2Core *net, DN_Str8 url, DN_Str8 meth static DN_NET2Request DN_NET2_OpenWS(DN_NET2Core *net, DN_Str8 url, DN_NET2DoHTTPArgs const *args) { - DN_NET2Request result = DN_NET2_DoRequest_(net, url, DN_STR8(""), args, DN_NET2RequestType_WS); + DN_NET2Request result = DN_NET2_DoRequest_(net, url, DN_Str8Lit(""), args, DN_NET2RequestType_WS); return result; } diff --git a/Source/Extra/dn_tests.cpp b/Source/Extra/dn_tests.cpp index 367695d..bd991dd 100644 --- a/Source/Extra/dn_tests.cpp +++ b/Source/Extra/dn_tests.cpp @@ -303,6 +303,41 @@ static DN_UTCore DN_Tests_Base() DN_UT_Assert(&result, DN_CPUHasFeature(&cpu_report, DN_CPUFeature_XSAVE) == DN_RefImplCPUReport::XSAVE()); #endif } + + for (DN_UT_Test(&result, "Age")) { + // NOTE: Seconds and milliseconds + { + DN_Str8x128 str8 = DN_AgeStr8FromMsU64(1001, DN_AgeUnit_Sec | DN_AgeUnit_Ms); + DN_Str8 expect = DN_Str8Lit("1s 1ms"); + DN_UT_AssertF(&result, DN_MemEq(str8.data, str8.size, expect.data, expect.size), "str8=%.*s, expect=%.*s", DN_Str8PrintFmt(str8), DN_Str8PrintFmt(expect)); + } + + // NOTE: Fractional seconds + { + DN_Str8x128 str8 = DN_AgeStr8FromMsU64(1001, DN_AgeUnit_FractionalSec); + DN_Str8 expect = DN_Str8Lit("1.001s"); + DN_UT_AssertF(&result, DN_MemEq(str8.data, str8.size, expect.data, expect.size), "str8=%.*s, expect=%.*s", DN_Str8PrintFmt(str8), DN_Str8PrintFmt(expect)); + } + } + + for (DN_UT_Test(&result, "String")) { + { + DN_Str8x32 str8 = DN_Str8x32FromU64(123456, ' '); + DN_Str8 expect = DN_Str8Lit("123 456"); + DN_UT_AssertF(&result, DN_Str8Eq(DN_Str8FromStruct(&str8), expect), "buf_str8=%.*s, expect=%.*s", DN_Str8PrintFmt(str8), DN_Str8PrintFmt(expect)); + } + } + + for (DN_UT_Test(&result, "Misc")) { + { + char buf[8] = {}; + DN_USize buf_size = 0; + DN_FmtAppendResult buf_str8 = DN_FmtAppendTruncate(buf, &buf_size, sizeof(buf), DN_Str8Lit("..."), "This string is longer than %d characters", DN_Cast(int)(sizeof(buf) - 1)); + DN_Str8 expect = DN_Str8Lit("This..."); // 7 characters long, 1 byte reserved for null-terminator + DN_UT_Assert(&result, buf_str8.truncated); + DN_UT_AssertF(&result, DN_Str8Eq(buf_str8.str8, expect), "buf_str8=%.*s, expect=%.*s", DN_Str8PrintFmt(buf_str8.str8), DN_Str8PrintFmt(expect)); + } + } } #endif // defined(DN_PLATFORM_WIN32) && defined(DN_COMPILER_MSVC) return result; @@ -316,27 +351,27 @@ static DN_UTCore DN_Tests_Arena() for (DN_UT_Test(&result, "Reused memory is zeroed out")) { uint8_t alignment = 1; DN_USize alloc_size = DN_Kilobytes(128); - DN_Arena arena = DN_Arena_FromVMem(0, 0, DN_ArenaFlags_Nil); + DN_Arena arena = DN_ArenaFromVMem(0, 0, DN_ArenaFlags_Nil); DN_DEFER { - DN_Arena_Deinit(&arena); + DN_ArenaDeinit(&arena); }; // NOTE: Allocate 128 kilobytes, fill it with garbage, then reset the arena uintptr_t first_ptr_address = 0; { - DN_ArenaTempMem temp_mem = DN_Arena_TempMemBegin(&arena); - void *ptr = DN_Arena_Alloc(&arena, alloc_size, alignment, DN_ZeroMem_Yes); - first_ptr_address = DN_CAST(uintptr_t) ptr; + DN_ArenaTempMem temp_mem = DN_ArenaTempMemBegin(&arena); + void *ptr = DN_ArenaAlloc(&arena, alloc_size, alignment, DN_ZMem_Yes); + first_ptr_address = DN_Cast(uintptr_t) ptr; DN_Memset(ptr, 'z', alloc_size); - DN_Arena_TempMemEnd(temp_mem); + DN_ArenaTempMemEnd(temp_mem); } // NOTE: Reallocate 128 kilobytes - char *ptr = DN_CAST(char *) DN_Arena_Alloc(&arena, alloc_size, alignment, DN_ZeroMem_Yes); + char *ptr = DN_Cast(char *) DN_ArenaAlloc(&arena, alloc_size, alignment, DN_ZMem_Yes); // NOTE: Double check we got the same pointer - DN_UT_Assert(&result, first_ptr_address == DN_CAST(uintptr_t) ptr); + DN_UT_Assert(&result, first_ptr_address == DN_Cast(uintptr_t) ptr); // NOTE: Check that the bytes are set to 0 for (DN_USize i = 0; i < alloc_size; i++) @@ -345,56 +380,56 @@ static DN_UTCore DN_Tests_Arena() for (DN_UT_Test(&result, "Test arena grows naturally, 1mb + 4mb")) { // NOTE: Allocate 1mb, then 4mb, this should force the arena to grow - DN_Arena arena = DN_Arena_FromVMem(DN_Megabytes(2), DN_Megabytes(2), DN_ArenaFlags_Nil); + DN_Arena arena = DN_ArenaFromVMem(DN_Megabytes(2), DN_Megabytes(2), DN_ArenaFlags_Nil); DN_DEFER { - DN_Arena_Deinit(&arena); + DN_ArenaDeinit(&arena); }; - char *ptr_1mb = DN_Arena_NewArray(&arena, char, DN_Megabytes(1), DN_ZeroMem_Yes); - char *ptr_4mb = DN_Arena_NewArray(&arena, char, DN_Megabytes(4), DN_ZeroMem_Yes); + char *ptr_1mb = DN_ArenaNewArray(&arena, char, DN_Megabytes(1), DN_ZMem_Yes); + char *ptr_4mb = DN_ArenaNewArray(&arena, char, DN_Megabytes(4), DN_ZMem_Yes); DN_UT_Assert(&result, ptr_1mb); DN_UT_Assert(&result, ptr_4mb); DN_ArenaBlock const *block_4mb_begin = arena.curr; - char const *block_4mb_end = DN_CAST(char *) block_4mb_begin + block_4mb_begin->reserve; + char const *block_4mb_end = DN_Cast(char *) block_4mb_begin + block_4mb_begin->reserve; DN_ArenaBlock const *block_1mb_begin = block_4mb_begin->prev; DN_UT_AssertF(&result, block_1mb_begin, "New block should have been allocated"); - char const *block_1mb_end = DN_CAST(char *) block_1mb_begin + block_1mb_begin->reserve; + char const *block_1mb_end = DN_Cast(char *) block_1mb_begin + block_1mb_begin->reserve; DN_UT_AssertF(&result, block_1mb_begin != block_4mb_begin, "New block should have been allocated and linked"); - DN_UT_AssertF(&result, ptr_1mb >= DN_CAST(char *) block_1mb_begin && ptr_1mb <= block_1mb_end, "Pointer was not allocated from correct memory block"); - DN_UT_AssertF(&result, ptr_4mb >= DN_CAST(char *) block_4mb_begin && ptr_4mb <= block_4mb_end, "Pointer was not allocated from correct memory block"); + DN_UT_AssertF(&result, ptr_1mb >= DN_Cast(char *) block_1mb_begin && ptr_1mb <= block_1mb_end, "Pointer was not allocated from correct memory block"); + DN_UT_AssertF(&result, ptr_4mb >= DN_Cast(char *) block_4mb_begin && ptr_4mb <= block_4mb_end, "Pointer was not allocated from correct memory block"); } for (DN_UT_Test(&result, "Test arena grows naturally, 1mb, temp memory 4mb")) { - DN_Arena arena = DN_Arena_FromVMem(DN_Megabytes(2), DN_Megabytes(2), DN_ArenaFlags_Nil); + DN_Arena arena = DN_ArenaFromVMem(DN_Megabytes(2), DN_Megabytes(2), DN_ArenaFlags_Nil); DN_DEFER { - DN_Arena_Deinit(&arena); + DN_ArenaDeinit(&arena); }; // NOTE: Allocate 1mb, then 4mb, this should force the arena to grow - char *ptr_1mb = DN_CAST(char *) DN_Arena_Alloc(&arena, DN_Megabytes(1), 1 /*align*/, DN_ZeroMem_Yes); + char *ptr_1mb = DN_Cast(char *) DN_ArenaAlloc(&arena, DN_Megabytes(1), 1 /*align*/, DN_ZMem_Yes); DN_UT_Assert(&result, ptr_1mb); - DN_ArenaTempMem temp_memory = DN_Arena_TempMemBegin(&arena); + DN_ArenaTempMem temp_memory = DN_ArenaTempMemBegin(&arena); { - char *ptr_4mb = DN_Arena_NewArray(&arena, char, DN_Megabytes(4), DN_ZeroMem_Yes); + char *ptr_4mb = DN_ArenaNewArray(&arena, char, DN_Megabytes(4), DN_ZMem_Yes); DN_UT_Assert(&result, ptr_4mb); DN_ArenaBlock const *block_4mb_begin = arena.curr; - char const *block_4mb_end = DN_CAST(char *) block_4mb_begin + block_4mb_begin->reserve; + char const *block_4mb_end = DN_Cast(char *) block_4mb_begin + block_4mb_begin->reserve; DN_ArenaBlock const *block_1mb_begin = block_4mb_begin->prev; - char const *block_1mb_end = DN_CAST(char *) block_1mb_begin + block_1mb_begin->reserve; + char const *block_1mb_end = DN_Cast(char *) block_1mb_begin + block_1mb_begin->reserve; DN_UT_AssertF(&result, block_1mb_begin != block_4mb_begin, "New block should have been allocated and linked"); - DN_UT_AssertF(&result, ptr_1mb >= DN_CAST(char *) block_1mb_begin && ptr_1mb <= block_1mb_end, "Pointer was not allocated from correct memory block"); - DN_UT_AssertF(&result, ptr_4mb >= DN_CAST(char *) block_4mb_begin && ptr_4mb <= block_4mb_end, "Pointer was not allocated from correct memory block"); + DN_UT_AssertF(&result, ptr_1mb >= DN_Cast(char *) block_1mb_begin && ptr_1mb <= block_1mb_end, "Pointer was not allocated from correct memory block"); + DN_UT_AssertF(&result, ptr_4mb >= DN_Cast(char *) block_4mb_begin && ptr_4mb <= block_4mb_end, "Pointer was not allocated from correct memory block"); } - DN_Arena_TempMemEnd(temp_memory); + DN_ArenaTempMemEnd(temp_memory); DN_UT_Assert(&result, arena.curr->prev == nullptr); DN_UT_AssertF(&result, arena.curr->reserve >= DN_Megabytes(1), @@ -414,79 +449,80 @@ static DN_UTCore DN_Tests_Bin() DN_UT_LogF(&test, "DN_Bin\n"); { for (DN_UT_Test(&test, "Convert 0x123")) { - uint64_t result = DN_CVT_U64FromHex(DN_STR8("0x123")); + uint64_t result = DN_U64FromHexStr8Unsafe(DN_Str8Lit("0x123")); DN_UT_AssertF(&test, result == 0x123, "result: %" PRIu64, result); } for (DN_UT_Test(&test, "Convert 0xFFFF")) { - uint64_t result = DN_CVT_U64FromHex(DN_STR8("0xFFFF")); + uint64_t result = DN_U64FromHexStr8Unsafe(DN_Str8Lit("0xFFFF")); DN_UT_AssertF(&test, result == 0xFFFF, "result: %" PRIu64, result); } for (DN_UT_Test(&test, "Convert FFFF")) { - uint64_t result = DN_CVT_U64FromHex(DN_STR8("FFFF")); + uint64_t result = DN_U64FromHexStr8Unsafe(DN_Str8Lit("FFFF")); DN_UT_AssertF(&test, result == 0xFFFF, "result: %" PRIu64, result); } for (DN_UT_Test(&test, "Convert abCD")) { - uint64_t result = DN_CVT_U64FromHex(DN_STR8("abCD")); + uint64_t result = DN_U64FromHexStr8Unsafe(DN_Str8Lit("abCD")); DN_UT_AssertF(&test, result == 0xabCD, "result: %" PRIu64, result); } for (DN_UT_Test(&test, "Convert 0xabCD")) { - uint64_t result = DN_CVT_U64FromHex(DN_STR8("0xabCD")); + uint64_t result = DN_U64FromHexStr8Unsafe(DN_Str8Lit("0xabCD")); DN_UT_AssertF(&test, result == 0xabCD, "result: %" PRIu64, result); } for (DN_UT_Test(&test, "Convert 0x")) { - uint64_t result = DN_CVT_U64FromHex(DN_STR8("0x")); + uint64_t result = DN_U64FromHexStr8Unsafe(DN_Str8Lit("0x")); DN_UT_AssertF(&test, result == 0x0, "result: %" PRIu64, result); } for (DN_UT_Test(&test, "Convert 0X")) { - uint64_t result = DN_CVT_U64FromHex(DN_STR8("0X")); + uint64_t result = DN_U64FromHexStr8Unsafe(DN_Str8Lit("0X")); DN_UT_AssertF(&test, result == 0x0, "result: %" PRIu64, result); } for (DN_UT_Test(&test, "Convert 3")) { - uint64_t result = DN_CVT_U64FromHex(DN_STR8("3")); + uint64_t result = DN_U64FromHexStr8Unsafe(DN_Str8Lit("3")); DN_UT_AssertF(&test, result == 3, "result: %" PRIu64, result); } for (DN_UT_Test(&test, "Convert f")) { - uint64_t result = DN_CVT_U64FromHex(DN_STR8("f")); - DN_UT_AssertF(&test, result == 0xf, "result: %" PRIu64, result); + DN_U64FromResult result = DN_U64FromHexStr8(DN_Str8Lit("f")); + DN_UT_Assert(&test, result.success); + DN_UT_Assert(&test, result.value == 0xf); } for (DN_UT_Test(&test, "Convert g")) { - uint64_t result = DN_CVT_U64FromHex(DN_STR8("g")); - DN_UT_AssertF(&test, result == 0, "result: %" PRIu64, result); + DN_U64FromResult result = DN_U64FromHexStr8(DN_Str8Lit("g")); + DN_UT_Assert(&test, !result.success); } for (DN_UT_Test(&test, "Convert -0x3")) { - uint64_t result = DN_CVT_U64FromHex(DN_STR8("-0x3")); - DN_UT_AssertF(&test, result == 0, "result: %" PRIu64, result); + DN_U64FromResult result = DN_U64FromHexStr8(DN_Str8Lit("-0x3")); + DN_UT_Assert(&test, !result.success); } uint32_t number = 0xd095f6; for (DN_UT_Test(&test, "Convert %x to string", number)) { - DN_Str8 number_hex = DN_CVT_HexFromBytes(tmem.arena, &number, sizeof(number)); - DN_UT_AssertF(&test, DN_Str8_Eq(number_hex, DN_STR8("f695d000")), "number_hex=%.*s", DN_STR_FMT(number_hex)); + DN_Str8 number_hex = DN_HexFromBytesPtrArena(&number, sizeof(number), tmem.arena); + DN_UT_AssertF(&test, DN_Str8Eq(number_hex, DN_Str8Lit("f695d000")), "number_hex=%.*s", DN_Str8PrintFmt(number_hex)); } number = 0xf6ed00; for (DN_UT_Test(&test, "Convert %x to string", number)) { - DN_Str8 number_hex = DN_CVT_HexFromBytes(tmem.arena, &number, sizeof(number)); - DN_UT_AssertF(&test, DN_Str8_Eq(number_hex, DN_STR8("00edf600")), "number_hex=%.*s", DN_STR_FMT(number_hex)); + DN_Str8 number_hex = DN_HexFromBytesPtrArena(&number, sizeof(number), tmem.arena); + DN_UT_AssertF(&test, DN_Str8Eq(number_hex, DN_Str8Lit("00edf600")), "number_hex=%.*s", DN_Str8PrintFmt(number_hex)); } - DN_Str8 hex = DN_STR8("0xf6ed00"); - for (DN_UT_Test(&test, "Convert %.*s to bytes", DN_STR_FMT(hex))) { - DN_Str8 bytes = DN_CVT_BytesFromHex(tmem.arena, hex); + DN_Str8 hex = DN_Str8Lit("0xf6ed00"); + for (DN_UT_Test(&test, "Convert %.*s to bytes", DN_Str8PrintFmt(hex))) { + DN_Str8 bytes = DN_BytesFromHexStr8Arena(hex, tmem.arena); DN_UT_AssertF(&test, - DN_Str8_Eq(bytes, DN_STR8("\xf6\xed\x00")), + DN_Str8Eq(bytes, DN_Str8Lit("\xf6\xed\x00")), "number_hex=%.*s", - DN_STR_FMT(DN_CVT_HexFromBytes(tmem.arena, bytes.data, bytes.size))); + DN_Str8PrintFmt(DN_HexFromBytesPtrArena(bytes.data, bytes.size, tmem.arena))); } } return test; @@ -808,16 +844,16 @@ static DN_UTCore DN_Tests_BaseContainers() { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); { - DN_Arena arena = DN_Arena_FromVMem(0, 0, DN_ArenaFlags_Nil); + DN_Arena arena = DN_ArenaFromVMem(0, 0, DN_ArenaFlags_Nil); uint32_t const MAP_SIZE = 64; DN_DSMap map = DN_DSMap_Init(&arena, MAP_SIZE, DN_DSMapFlags_Nil); DN_DEFER { - DN_DSMap_Deinit(&map, DN_ZeroMem_Yes); + DN_DSMap_Deinit(&map, DN_ZMem_Yes); }; for (DN_UT_Test(&result, "Find non-existent value")) { - DN_DSMapResult find = DN_DSMap_FindKeyStr8(&map, DN_STR8("Foo")); + DN_DSMapResult find = DN_DSMap_FindKeyStr8(&map, DN_Str8Lit("Foo")); DN_UT_Assert(&result, !find.found); DN_UT_Assert(&result, map.size == MAP_SIZE); DN_UT_Assert(&result, map.initial_size == MAP_SIZE); @@ -856,20 +892,20 @@ static DN_UTCore DN_Tests_BaseContainers() for (int result_type = 0; result_type < DSMapTestType_Count; result_type++) { DN_Str8 prefix = {}; switch (result_type) { - case DSMapTestType_Set: prefix = DN_STR8("Set"); break; - case DSMapTestType_MakeSlot: prefix = DN_STR8("Make slot"); break; + case DSMapTestType_Set: prefix = DN_Str8Lit("Set"); break; + case DSMapTestType_MakeSlot: prefix = DN_Str8Lit("Make slot"); break; } DN_ArenaTempMemScope temp_mem_scope = DN_ArenaTempMemScope(tmem.arena); - DN_Arena arena = DN_Arena_FromVMem(0, 0, DN_ArenaFlags_Nil); + DN_Arena arena = DN_ArenaFromVMem(0, 0, DN_ArenaFlags_Nil); uint32_t const MAP_SIZE = 64; DN_DSMap map = DN_DSMap_Init(&arena, MAP_SIZE, DN_DSMapFlags_Nil); DN_DEFER { - DN_DSMap_Deinit(&map, DN_ZeroMem_Yes); + DN_DSMap_Deinit(&map, DN_ZMem_Yes); }; - for (DN_UT_Test(&result, "%.*s: Test growing", DN_STR_FMT(prefix))) { + for (DN_UT_Test(&result, "%.*s: Test growing", DN_Str8PrintFmt(prefix))) { uint64_t map_start_size = map.size; uint64_t value = 0; uint64_t grow_threshold = map_start_size * 3 / 4; @@ -904,13 +940,13 @@ static DN_UTCore DN_Tests_BaseContainers() } } - for (DN_UT_Test(&result, "%.*s: Check the sentinel is present", DN_STR_FMT(prefix))) { + for (DN_UT_Test(&result, "%.*s: Check the sentinel is present", DN_Str8PrintFmt(prefix))) { DN_DSMapSlot NIL_SLOT = {}; DN_DSMapSlot sentinel = map.slots[DN_DS_MAP_SENTINEL_SLOT]; DN_UT_Assert(&result, DN_Memcmp(&sentinel, &NIL_SLOT, sizeof(NIL_SLOT)) == 0); } - for (DN_UT_Test(&result, "%.*s: Recheck all the hash tables values after growing", DN_STR_FMT(prefix))) { + for (DN_UT_Test(&result, "%.*s: Recheck all the hash tables values after growing", DN_Str8PrintFmt(prefix))) { for (uint64_t index = 1 /*Sentinel*/; index < map.occupied; index++) { DN_DSMapSlot const *slot = map.slots + index; @@ -930,7 +966,7 @@ static DN_UTCore DN_Tests_BaseContainers() } } - for (DN_UT_Test(&result, "%.*s: Test shrinking", DN_STR_FMT(prefix))) { + for (DN_UT_Test(&result, "%.*s: Test shrinking", DN_Str8PrintFmt(prefix))) { uint64_t start_map_size = map.size; uint64_t start_map_occupied = map.occupied; uint64_t value = 0; @@ -1008,7 +1044,7 @@ static DN_UTCore DN_Tests_BaseContainers() array.max = DN_ArrayCountU(array_buffer); for (DN_UT_Test(&result, "Make item")) { - int *item = DN_IArray_Make(&array, DN_ZeroMem_Yes); + int *item = DN_IArray_Make(&array, DN_ZMem_Yes); DN_UT_Assert(&result, item && array.size == 1); } } @@ -1307,8 +1343,8 @@ static DN_UTCore DN_Tests_BaseContainers() // NOTE: Verify that the items returned from the data array are // contiguous in memory. - UnalignedObject *make_item_a = DN_VArray_MakeArray(&array, 1, DN_ZeroMem_Yes); - UnalignedObject *make_item_b = DN_VArray_MakeArray(&array, 1, DN_ZeroMem_Yes); + UnalignedObject *make_item_a = DN_VArray_MakeArray(&array, 1, DN_ZMem_Yes); + UnalignedObject *make_item_b = DN_VArray_MakeArray(&array, 1, DN_ZMem_Yes); DN_Memset(make_item_a->data, 'a', sizeof(make_item_a->data)); DN_Memset(make_item_b->data, 'b', sizeof(make_item_b->data)); DN_UT_Assert(&result, (uintptr_t)make_item_b == (uintptr_t)(make_item_a + 1)); @@ -1387,7 +1423,7 @@ static DN_UTCore DN_Tests_Intrinsics() for (DN_UT_Test(&result, "DN_AtomicSetValue64")) { int64_t a = 0; int64_t b = 111; - DN_AtomicSetValue64(DN_CAST(uint64_t *) & a, b); + DN_AtomicSetValue64(DN_Cast(uint64_t *) & a, b); DN_UT_AssertF(&result, a == b, "a: %" PRId64 ", b: %" PRId64, a, b); } @@ -1603,7 +1639,7 @@ enum DN_Tests__HashType DN_Str8 const DN_UT_HASH_STRING_[] = { - #define DN_UT_HASH_X_ENTRY(enum_val, string) DN_STR8(string), + #define DN_UT_HASH_X_ENTRY(enum_val, string) DN_Str8Lit(string), DN_UT_HASH_X_MACRO #undef DN_UT_HASH_X_ENTRY }; @@ -1617,13 +1653,13 @@ void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input) case Hash_SHA3_224: { DN_KCBytes28 hash = DN_KC_SHA3_224Str8(input); DN_KCBytes28 expect; - DN_RefImpl_FIPS202_SHA3_224_(DN_CAST(uint8_t *) input.data, input.size, (uint8_t *)expect.data); + DN_RefImpl_FIPS202_SHA3_224_(DN_Cast(uint8_t *) input.data, input.size, (uint8_t *)expect.data); DN_UT_AssertF(test, DN_KC_Bytes28Equals(&hash, &expect), "\ninput: %.*s" "\nhash: %.*s" "\nexpect: %.*s", - DN_STR_FMT(input_hex), + DN_Str8PrintFmt(input_hex), DN_KC_STRING56_FMT(DN_KC_Bytes28ToHex(&hash).data), DN_KC_STRING56_FMT(DN_KC_Bytes28ToHex(&expect).data)); } break; @@ -1631,13 +1667,13 @@ void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input) case Hash_SHA3_256: { DN_KCBytes32 hash = DN_KC_SHA3_256Str8(input); DN_KCBytes32 expect; - DN_RefImpl_FIPS202_SHA3_256_(DN_CAST(uint8_t *) input.data, input.size, (uint8_t *)expect.data); + DN_RefImpl_FIPS202_SHA3_256_(DN_Cast(uint8_t *) input.data, input.size, (uint8_t *)expect.data); DN_UT_AssertF(test, DN_KC_Bytes32Equals(&hash, &expect), "\ninput: %.*s" "\nhash: %.*s" "\nexpect: %.*s", - DN_STR_FMT(input_hex), + DN_Str8PrintFmt(input_hex), DN_KC_STRING64_FMT(DN_KC_Bytes32ToHex(&hash).data), DN_KC_STRING64_FMT(DN_KC_Bytes32ToHex(&expect).data)); } break; @@ -1645,13 +1681,13 @@ void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input) case Hash_SHA3_384: { DN_KCBytes48 hash = DN_KC_SHA3_384Str8(input); DN_KCBytes48 expect; - DN_RefImpl_FIPS202_SHA3_384_(DN_CAST(uint8_t *) input.data, input.size, (uint8_t *)expect.data); + DN_RefImpl_FIPS202_SHA3_384_(DN_Cast(uint8_t *) input.data, input.size, (uint8_t *)expect.data); DN_UT_AssertF(test, DN_KC_Bytes48Equals(&hash, &expect), "\ninput: %.*s" "\nhash: %.*s" "\nexpect: %.*s", - DN_STR_FMT(input_hex), + DN_Str8PrintFmt(input_hex), DN_KC_STRING96_FMT(DN_KC_Bytes48ToHex(&hash).data), DN_KC_STRING96_FMT(DN_KC_Bytes48ToHex(&expect).data)); } break; @@ -1659,13 +1695,13 @@ void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input) case Hash_SHA3_512: { DN_KCBytes64 hash = DN_KC_SHA3_512Str8(input); DN_KCBytes64 expect; - DN_RefImpl_FIPS202_SHA3_512_(DN_CAST(uint8_t *) input.data, input.size, (uint8_t *)expect.data); + DN_RefImpl_FIPS202_SHA3_512_(DN_Cast(uint8_t *) input.data, input.size, (uint8_t *)expect.data); DN_UT_AssertF(test, DN_KC_Bytes64Equals(&hash, &expect), "\ninput: %.*s" "\nhash: %.*s" "\nexpect: %.*s", - DN_STR_FMT(input_hex), + DN_Str8PrintFmt(input_hex), DN_KC_STRING128_FMT(DN_KC_Bytes64ToHex(&hash).data), DN_KC_STRING128_FMT(DN_KC_Bytes64ToHex(&expect).data)); } break; @@ -1673,13 +1709,13 @@ void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input) case Hash_Keccak_224: { DN_KCBytes28 hash = DN_KC_Keccak224Str8(input); DN_KCBytes28 expect; - DN_RefImpl_Keccak_(1152, 448, DN_CAST(uint8_t *) input.data, input.size, 0x01, (uint8_t *)expect.data, sizeof(expect)); + DN_RefImpl_Keccak_(1152, 448, DN_Cast(uint8_t *) input.data, input.size, 0x01, (uint8_t *)expect.data, sizeof(expect)); DN_UT_AssertF(test, DN_KC_Bytes28Equals(&hash, &expect), "\ninput: %.*s" "\nhash: %.*s" "\nexpect: %.*s", - DN_STR_FMT(input_hex), + DN_Str8PrintFmt(input_hex), DN_KC_STRING56_FMT(DN_KC_Bytes28ToHex(&hash).data), DN_KC_STRING56_FMT(DN_KC_Bytes28ToHex(&expect).data)); } break; @@ -1687,13 +1723,13 @@ void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input) case Hash_Keccak_256: { DN_KCBytes32 hash = DN_KC_Keccak256Str8(input); DN_KCBytes32 expect; - DN_RefImpl_Keccak_(1088, 512, DN_CAST(uint8_t *) input.data, input.size, 0x01, (uint8_t *)expect.data, sizeof(expect)); + DN_RefImpl_Keccak_(1088, 512, DN_Cast(uint8_t *) input.data, input.size, 0x01, (uint8_t *)expect.data, sizeof(expect)); DN_UT_AssertF(test, DN_KC_Bytes32Equals(&hash, &expect), "\ninput: %.*s" "\nhash: %.*s" "\nexpect: %.*s", - DN_STR_FMT(input_hex), + DN_Str8PrintFmt(input_hex), DN_KC_STRING64_FMT(DN_KC_Bytes32ToHex(&hash).data), DN_KC_STRING64_FMT(DN_KC_Bytes32ToHex(&expect).data)); } break; @@ -1701,13 +1737,13 @@ void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input) case Hash_Keccak_384: { DN_KCBytes48 hash = DN_KC_Keccak384Str8(input); DN_KCBytes48 expect; - DN_RefImpl_Keccak_(832, 768, DN_CAST(uint8_t *) input.data, input.size, 0x01, (uint8_t *)expect.data, sizeof(expect)); + DN_RefImpl_Keccak_(832, 768, DN_Cast(uint8_t *) input.data, input.size, 0x01, (uint8_t *)expect.data, sizeof(expect)); DN_UT_AssertF(test, DN_KC_Bytes48Equals(&hash, &expect), "\ninput: %.*s" "\nhash: %.*s" "\nexpect: %.*s", - DN_STR_FMT(input_hex), + DN_Str8PrintFmt(input_hex), DN_KC_STRING96_FMT(DN_KC_Bytes48ToHex(&hash).data), DN_KC_STRING96_FMT(DN_KC_Bytes48ToHex(&expect).data)); } break; @@ -1715,13 +1751,13 @@ void DN_Tests_KeccakDispatch_(DN_UTCore *test, int hash_type, DN_Str8 input) case Hash_Keccak_512: { DN_KCBytes64 hash = DN_KC_Keccak512Str8(input); DN_KCBytes64 expect; - DN_RefImpl_Keccak_(576, 1024, DN_CAST(uint8_t *) input.data, input.size, 0x01, (uint8_t *)expect.data, sizeof(expect)); + DN_RefImpl_Keccak_(576, 1024, DN_Cast(uint8_t *) input.data, input.size, 0x01, (uint8_t *)expect.data, sizeof(expect)); DN_UT_AssertF(test, DN_KC_Bytes64Equals(&hash, &expect), "\ninput: %.*s" "\nhash: %.*s" "\nexpect: %.*s", - DN_STR_FMT(input_hex), + DN_Str8PrintFmt(input_hex), DN_KC_STRING128_FMT(DN_KC_Bytes64ToHex(&hash).data), DN_KC_STRING128_FMT(DN_KC_Bytes64ToHex(&expect).data)); } break; @@ -1732,10 +1768,10 @@ DN_UTCore DN_Tests_Keccak() { DN_UTCore test = DN_UT_Init(); DN_Str8 const INPUTS[] = { - DN_STR8("abc"), - DN_STR8(""), - DN_STR8("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"), - DN_STR8("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmno" + DN_Str8Lit("abc"), + DN_Str8Lit(""), + DN_Str8Lit("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"), + DN_Str8Lit("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmno" "pqrstnopqrstu"), }; @@ -1744,20 +1780,20 @@ DN_UTCore DN_Tests_Keccak() for (int hash_type = 0; hash_type < Hash_Count; hash_type++) { DN_PCG32 rng = DN_PCG32_Init(0xd48e'be21'2af8'733d); for (DN_Str8 input : INPUTS) { - DN_UT_BeginF(&test, "%.*s - Input: %.*s", DN_STR_FMT(DN_UT_HASH_STRING_[hash_type]), DN_CAST(int) DN_Min(input.size, 54), input.data); + DN_UT_BeginF(&test, "%.*s - Input: %.*s", DN_Str8PrintFmt(DN_UT_HASH_STRING_[hash_type]), DN_Cast(int) DN_Min(input.size, 54), input.data); DN_Tests_KeccakDispatch_(&test, hash_type, input); DN_UT_End(&test); } - DN_UT_BeginF(&test, "%.*s - Deterministic random inputs", DN_STR_FMT(DN_UT_HASH_STRING_[hash_type])); + DN_UT_BeginF(&test, "%.*s - Deterministic random inputs", DN_Str8PrintFmt(DN_UT_HASH_STRING_[hash_type])); for (DN_USize index = 0; index < 128; index++) { char src[4096] = {}; uint32_t src_size = DN_PCG32_Range(&rng, 0, sizeof(src)); for (DN_USize src_index = 0; src_index < src_size; src_index++) - src[src_index] = DN_CAST(char) DN_PCG32_Range(&rng, 0, 255); + src[src_index] = DN_Cast(char) DN_PCG32_Range(&rng, 0, 255); - DN_Str8 input = DN_Str8_Init(src, src_size); + DN_Str8 input = DN_Str8FromPtr(src, src_size); DN_Tests_KeccakDispatch_(&test, hash_type, input); } DN_UT_End(&test); @@ -1813,8 +1849,8 @@ static DN_UTCore DN_Tests_OS() for (DN_UT_Test(&result, "Query executable directory")) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); DN_Str8 os_result = DN_OS_EXEDir(tmem.arena); - DN_UT_Assert(&result, DN_Str8_HasData(os_result)); - DN_UT_AssertF(&result, DN_OS_PathIsDir(os_result), "result(%zu): %.*s", os_result.size, DN_STR_FMT(os_result)); + DN_UT_Assert(&result, os_result.size); + DN_UT_AssertF(&result, DN_OS_PathIsDir(os_result), "result(%zu): %.*s", os_result.size, DN_Str8PrintFmt(os_result)); } for (DN_UT_Test(&result, "DN_OS_PerfCounterNow")) { @@ -1844,37 +1880,37 @@ static DN_UTCore DN_Tests_OS() DN_UT_LogF(&result, "\nDN_OS Filesystem\n"); { for (DN_UT_Test(&result, "Make directory recursive \"abcd/efgh\"")) { - DN_UT_AssertF(&result, DN_OS_PathMakeDir(DN_STR8("abcd/efgh")), "Failed to make directory"); - DN_UT_AssertF(&result, DN_OS_PathIsDir(DN_STR8("abcd")), "Directory was not made"); - DN_UT_AssertF(&result, DN_OS_PathIsDir(DN_STR8("abcd/efgh")), "Subdirectory was not made"); - DN_UT_AssertF(&result, DN_OS_PathIsFile(DN_STR8("abcd")) == false, "This function should only return true for files"); - DN_UT_AssertF(&result, DN_OS_PathIsFile(DN_STR8("abcd/efgh")) == false, "This function should only return true for files"); - DN_UT_AssertF(&result, DN_OS_PathDelete(DN_STR8("abcd/efgh")), "Failed to delete directory"); - DN_UT_AssertF(&result, DN_OS_PathDelete(DN_STR8("abcd")), "Failed to cleanup directory"); + DN_UT_AssertF(&result, DN_OS_PathMakeDir(DN_Str8Lit("abcd/efgh")), "Failed to make directory"); + DN_UT_AssertF(&result, DN_OS_PathIsDir(DN_Str8Lit("abcd")), "Directory was not made"); + DN_UT_AssertF(&result, DN_OS_PathIsDir(DN_Str8Lit("abcd/efgh")), "Subdirectory was not made"); + DN_UT_AssertF(&result, DN_OS_PathIsFile(DN_Str8Lit("abcd")) == false, "This function should only return true for files"); + DN_UT_AssertF(&result, DN_OS_PathIsFile(DN_Str8Lit("abcd/efgh")) == false, "This function should only return true for files"); + DN_UT_AssertF(&result, DN_OS_PathDelete(DN_Str8Lit("abcd/efgh")), "Failed to delete directory"); + DN_UT_AssertF(&result, DN_OS_PathDelete(DN_Str8Lit("abcd")), "Failed to cleanup directory"); } for (DN_UT_Test(&result, "File write, read, copy, move and delete")) { // NOTE: Write step - DN_Str8 const SRC_FILE = DN_STR8("dn_result_file"); - DN_B32 write_result = DN_OS_FileWriteAll(SRC_FILE, DN_STR8("1234"), nullptr); + DN_Str8 const SRC_FILE = DN_Str8Lit("dn_result_file"); + DN_B32 write_result = DN_OS_FileWriteAll(SRC_FILE, DN_Str8Lit("1234"), nullptr); DN_UT_Assert(&result, write_result); DN_UT_Assert(&result, DN_OS_PathIsFile(SRC_FILE)); // NOTE: Read step DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); DN_Str8 read_file = DN_OS_FileReadAllArena(tmem.arena, SRC_FILE, nullptr); - DN_UT_AssertF(&result, DN_Str8_HasData(read_file), "Failed to load file"); + DN_UT_AssertF(&result, read_file.size, "Failed to load file"); DN_UT_AssertF(&result, read_file.size == 4, "File read wrong amount of bytes (%zu)", read_file.size); - DN_UT_AssertF(&result, DN_Str8_Eq(read_file, DN_STR8("1234")), "Read %zu bytes instead of the expected 4: '%.*s'", read_file.size, DN_STR_FMT(read_file)); + DN_UT_AssertF(&result, DN_Str8Eq(read_file, DN_Str8Lit("1234")), "Read %zu bytes instead of the expected 4: '%.*s'", read_file.size, DN_Str8PrintFmt(read_file)); // NOTE: Copy step - DN_Str8 const COPY_FILE = DN_STR8("dn_result_file_copy"); + DN_Str8 const COPY_FILE = DN_Str8Lit("dn_result_file_copy"); DN_B32 copy_result = DN_OS_FileCopy(SRC_FILE, COPY_FILE, true /*overwrite*/, nullptr); DN_UT_Assert(&result, copy_result); DN_UT_Assert(&result, DN_OS_PathIsFile(COPY_FILE)); // NOTE: Move step - DN_Str8 const MOVE_FILE = DN_STR8("dn_result_file_move"); + DN_Str8 const MOVE_FILE = DN_Str8Lit("dn_result_file_move"); DN_B32 move_result = DN_OS_FileMove(COPY_FILE, MOVE_FILE, true /*overwrite*/, nullptr); DN_UT_Assert(&result, move_result); DN_UT_Assert(&result, DN_OS_PathIsFile(MOVE_FILE)); @@ -2079,7 +2115,7 @@ static DN_UTCore DN_Tests_Str8() DN_UT_LogF(&result, "DN_Str8\n"); { for (DN_UT_Test(&result, "Initialise with string literal w/ macro")) { - DN_Str8 string = DN_STR8("AB"); + DN_Str8 string = DN_Str8Lit("AB"); DN_UT_AssertF(&result, string.size == 2, "size: %zu", string.size); DN_UT_AssertF(&result, string.data[0] == 'A', "string[0]: %c", string.data[0]); DN_UT_AssertF(&result, string.data[1] == 'B', "string[1]: %c", string.data[1]); @@ -2087,7 +2123,7 @@ static DN_UTCore DN_Tests_Str8() for (DN_UT_Test(&result, "Initialise with format string")) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 string = DN_Str8_FromF(tmem.arena, "%s", "AB"); + DN_Str8 string = DN_Str8FromFmtArena(tmem.arena, "%s", "AB"); DN_UT_AssertF(&result, string.size == 2, "size: %zu", string.size); DN_UT_AssertF(&result, string.data[0] == 'A', "string[0]: %c", string.data[0]); DN_UT_AssertF(&result, string.data[1] == 'B', "string[1]: %c", string.data[1]); @@ -2096,8 +2132,8 @@ static DN_UTCore DN_Tests_Str8() for (DN_UT_Test(&result, "Copy string")) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 string = DN_STR8("AB"); - DN_Str8 copy = DN_Str8_FromStr8(tmem.arena, string); + DN_Str8 string = DN_Str8Lit("AB"); + DN_Str8 copy = DN_Str8FromStr8Arena(tmem.arena, string); DN_UT_AssertF(&result, copy.size == 2, "size: %zu", copy.size); DN_UT_AssertF(&result, copy.data[0] == 'A', "copy[0]: %c", copy.data[0]); DN_UT_AssertF(&result, copy.data[1] == 'B', "copy[1]: %c", copy.data[1]); @@ -2105,226 +2141,209 @@ static DN_UTCore DN_Tests_Str8() } for (DN_UT_Test(&result, "Trim whitespace around string")) { - DN_Str8 string = DN_Str8_TrimWhitespaceAround(DN_STR8(" AB ")); - DN_UT_AssertF(&result, DN_Str8_Eq(string, DN_STR8("AB")), "[string=%.*s]", DN_STR_FMT(string)); + DN_Str8 string = DN_Str8TrimWhitespaceAround(DN_Str8Lit(" AB ")); + DN_UT_AssertF(&result, DN_Str8Eq(string, DN_Str8Lit("AB")), "[string=%.*s]", DN_Str8PrintFmt(string)); } for (DN_UT_Test(&result, "Allocate string from arena")) { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 string = DN_Str8_Alloc(tmem.arena, 2, DN_ZeroMem_No); + DN_Str8 string = DN_Str8FromArena(tmem.arena, 2, DN_ZMem_No); DN_UT_AssertF(&result, string.size == 2, "size: %zu", string.size); } // NOTE: TrimPrefix/Suffix ///////////////////////////////////////////////////////////////////// for (DN_UT_Test(&result, "Trim prefix with matching prefix")) { - DN_Str8 input = DN_STR8("nft/abc"); - DN_Str8 str_result = DN_Str8_TrimPrefix(input, DN_STR8("nft/")); - DN_UT_AssertF(&result, DN_Str8_Eq(str_result, DN_STR8("abc")), "%.*s", DN_STR_FMT(str_result)); + DN_Str8 input = DN_Str8Lit("nft/abc"); + DN_Str8 str_result = DN_Str8TrimPrefix(input, DN_Str8Lit("nft/")); + DN_UT_AssertF(&result, DN_Str8Eq(str_result, DN_Str8Lit("abc")), "%.*s", DN_Str8PrintFmt(str_result)); } for (DN_UT_Test(&result, "Trim prefix with non matching prefix")) { - DN_Str8 input = DN_STR8("nft/abc"); - DN_Str8 str_result = DN_Str8_TrimPrefix(input, DN_STR8(" ft/")); - DN_UT_AssertF(&result, DN_Str8_Eq(str_result, input), "%.*s", DN_STR_FMT(str_result)); + DN_Str8 input = DN_Str8Lit("nft/abc"); + DN_Str8 str_result = DN_Str8TrimPrefix(input, DN_Str8Lit(" ft/")); + DN_UT_AssertF(&result, DN_Str8Eq(str_result, input), "%.*s", DN_Str8PrintFmt(str_result)); } for (DN_UT_Test(&result, "Trim suffix with matching suffix")) { - DN_Str8 input = DN_STR8("nft/abc"); - DN_Str8 str_result = DN_Str8_TrimSuffix(input, DN_STR8("abc")); - DN_UT_AssertF(&result, DN_Str8_Eq(str_result, DN_STR8("nft/")), "%.*s", DN_STR_FMT(str_result)); + DN_Str8 input = DN_Str8Lit("nft/abc"); + DN_Str8 str_result = DN_Str8TrimSuffix(input, DN_Str8Lit("abc")); + DN_UT_AssertF(&result, DN_Str8Eq(str_result, DN_Str8Lit("nft/")), "%.*s", DN_Str8PrintFmt(str_result)); } for (DN_UT_Test(&result, "Trim suffix with non matching suffix")) { - DN_Str8 input = DN_STR8("nft/abc"); - DN_Str8 str_result = DN_Str8_TrimSuffix(input, DN_STR8("ab")); - DN_UT_AssertF(&result, DN_Str8_Eq(str_result, input), "%.*s", DN_STR_FMT(str_result)); + DN_Str8 input = DN_Str8Lit("nft/abc"); + DN_Str8 str_result = DN_Str8TrimSuffix(input, DN_Str8Lit("ab")); + DN_UT_AssertF(&result, DN_Str8Eq(str_result, input), "%.*s", DN_Str8PrintFmt(str_result)); } - // NOTE: DN_Str8_IsAllDigits ////////////////////////////////////////////////////////////// + // NOTE: DN_Str8IsAllDigits ////////////////////////////////////////////////////////////// for (DN_UT_Test(&result, "Is all digits fails on non-digit string")) { - DN_B32 str_result = DN_Str8_IsAll(DN_STR8("@123string"), DN_Str8IsAll_Digits); + DN_B32 str_result = DN_Str8IsAll(DN_Str8Lit("@123string"), DN_Str8IsAllType_Digits); DN_UT_Assert(&result, str_result == false); } for (DN_UT_Test(&result, "Is all digits fails on nullptr")) { - DN_B32 str_result = DN_Str8_IsAll(DN_Str8_Init(nullptr, 0), DN_Str8IsAll_Digits); - DN_UT_Assert(&result, str_result == false); - } - - for (DN_UT_Test(&result, "Is all digits fails on nullptr w/ size")) { - DN_B32 str_result = DN_Str8_IsAll(DN_Str8_Init(nullptr, 1), DN_Str8IsAll_Digits); + DN_B32 str_result = DN_Str8IsAll(DN_Str8FromPtr(nullptr, 0), DN_Str8IsAllType_Digits); DN_UT_Assert(&result, str_result == false); } for (DN_UT_Test(&result, "Is all digits fails on string w/ 0 size")) { char const buf[] = "@123string"; - DN_B32 str_result = DN_Str8_IsAll(DN_Str8_Init(buf, 0), DN_Str8IsAll_Digits); + DN_B32 str_result = DN_Str8IsAll(DN_Str8FromPtr(buf, 0), DN_Str8IsAllType_Digits); DN_UT_Assert(&result, !str_result); } for (DN_UT_Test(&result, "Is all digits success")) { - DN_B32 str_result = DN_Str8_IsAll(DN_STR8("23"), DN_Str8IsAll_Digits); - DN_UT_Assert(&result, DN_CAST(bool) str_result == true); + DN_B32 str_result = DN_Str8IsAll(DN_Str8Lit("23"), DN_Str8IsAllType_Digits); + DN_UT_Assert(&result, DN_Cast(bool) str_result == true); } for (DN_UT_Test(&result, "Is all digits fails on whitespace")) { - DN_B32 str_result = DN_Str8_IsAll(DN_STR8("23 "), DN_Str8IsAll_Digits); - DN_UT_Assert(&result, DN_CAST(bool) str_result == false); + DN_B32 str_result = DN_Str8IsAll(DN_Str8Lit("23 "), DN_Str8IsAllType_Digits); + DN_UT_Assert(&result, DN_Cast(bool) str_result == false); } - // NOTE: DN_Str8_BSplit /////////////////////////////////////////////////////////////////// + // NOTE: DN_Str8BSplit /////////////////////////////////////////////////////////////////// { { char const *TEST_FMT = "Binary split \"%.*s\" with \"%.*s\""; - DN_Str8 delimiter = DN_STR8("/"); - DN_Str8 input = DN_STR8("abcdef"); - for (DN_UT_Test(&result, TEST_FMT, DN_STR_FMT(input), DN_STR_FMT(delimiter))) { - DN_Str8BSplitResult split = DN_Str8_BSplit(input, delimiter); - DN_UT_AssertF(&result, DN_Str8_Eq(split.lhs, DN_STR8("abcdef")), "[lhs=%.*s]", DN_STR_FMT(split.lhs)); - DN_UT_AssertF(&result, DN_Str8_Eq(split.rhs, DN_STR8("")), "[rhs=%.*s]", DN_STR_FMT(split.rhs)); + DN_Str8 delimiter = DN_Str8Lit("/"); + DN_Str8 input = DN_Str8Lit("abcdef"); + for (DN_UT_Test(&result, TEST_FMT, DN_Str8PrintFmt(input), DN_Str8PrintFmt(delimiter))) { + DN_Str8BSplitResult split = DN_Str8BSplit(input, delimiter); + DN_UT_AssertF(&result, DN_Str8Eq(split.lhs, DN_Str8Lit("abcdef")), "[lhs=%.*s]", DN_Str8PrintFmt(split.lhs)); + DN_UT_AssertF(&result, DN_Str8Eq(split.rhs, DN_Str8Lit("")), "[rhs=%.*s]", DN_Str8PrintFmt(split.rhs)); } - input = DN_STR8("abc/def"); - for (DN_UT_Test(&result, TEST_FMT, DN_STR_FMT(input), DN_STR_FMT(delimiter))) { - DN_Str8BSplitResult split = DN_Str8_BSplit(input, delimiter); - DN_UT_AssertF(&result, DN_Str8_Eq(split.lhs, DN_STR8("abc")), "[lhs=%.*s]", DN_STR_FMT(split.lhs)); - DN_UT_AssertF(&result, DN_Str8_Eq(split.rhs, DN_STR8("def")), "[rhs=%.*s]", DN_STR_FMT(split.rhs)); + input = DN_Str8Lit("abc/def"); + for (DN_UT_Test(&result, TEST_FMT, DN_Str8PrintFmt(input), DN_Str8PrintFmt(delimiter))) { + DN_Str8BSplitResult split = DN_Str8BSplit(input, delimiter); + DN_UT_AssertF(&result, DN_Str8Eq(split.lhs, DN_Str8Lit("abc")), "[lhs=%.*s]", DN_Str8PrintFmt(split.lhs)); + DN_UT_AssertF(&result, DN_Str8Eq(split.rhs, DN_Str8Lit("def")), "[rhs=%.*s]", DN_Str8PrintFmt(split.rhs)); } - input = DN_STR8("/abcdef"); - for (DN_UT_Test(&result, TEST_FMT, DN_STR_FMT(input), DN_STR_FMT(delimiter))) { - DN_Str8BSplitResult split = DN_Str8_BSplit(input, delimiter); - DN_UT_AssertF(&result, DN_Str8_Eq(split.lhs, DN_STR8("")), "[lhs=%.*s]", DN_STR_FMT(split.lhs)); - DN_UT_AssertF(&result, DN_Str8_Eq(split.rhs, DN_STR8("abcdef")), "[rhs=%.*s]", DN_STR_FMT(split.rhs)); + input = DN_Str8Lit("/abcdef"); + for (DN_UT_Test(&result, TEST_FMT, DN_Str8PrintFmt(input), DN_Str8PrintFmt(delimiter))) { + DN_Str8BSplitResult split = DN_Str8BSplit(input, delimiter); + DN_UT_AssertF(&result, DN_Str8Eq(split.lhs, DN_Str8Lit("")), "[lhs=%.*s]", DN_Str8PrintFmt(split.lhs)); + DN_UT_AssertF(&result, DN_Str8Eq(split.rhs, DN_Str8Lit("abcdef")), "[rhs=%.*s]", DN_Str8PrintFmt(split.rhs)); } } { - DN_Str8 delimiter = DN_STR8("-=-"); - DN_Str8 input = DN_STR8("123-=-456"); - for (DN_UT_Test(&result, "Binary split \"%.*s\" with \"%.*s\"", DN_STR_FMT(input), DN_STR_FMT(delimiter))) { - DN_Str8BSplitResult split = DN_Str8_BSplit(input, delimiter); - DN_UT_AssertF(&result, DN_Str8_Eq(split.lhs, DN_STR8("123")), "[lhs=%.*s]", DN_STR_FMT(split.lhs)); - DN_UT_AssertF(&result, DN_Str8_Eq(split.rhs, DN_STR8("456")), "[rhs=%.*s]", DN_STR_FMT(split.rhs)); + DN_Str8 delimiter = DN_Str8Lit("-=-"); + DN_Str8 input = DN_Str8Lit("123-=-456"); + for (DN_UT_Test(&result, "Binary split \"%.*s\" with \"%.*s\"", DN_Str8PrintFmt(input), DN_Str8PrintFmt(delimiter))) { + DN_Str8BSplitResult split = DN_Str8BSplit(input, delimiter); + DN_UT_AssertF(&result, DN_Str8Eq(split.lhs, DN_Str8Lit("123")), "[lhs=%.*s]", DN_Str8PrintFmt(split.lhs)); + DN_UT_AssertF(&result, DN_Str8Eq(split.rhs, DN_Str8Lit("456")), "[rhs=%.*s]", DN_Str8PrintFmt(split.rhs)); } } } - // NOTE: DN_Str8_ToI64 ///////////////////////////////////////////////////////////////////////// - for (DN_UT_Test(&result, "To I64: Convert null string")) { - DN_Str8ToI64Result str_result = DN_Str8_ToI64(DN_Str8_Init(nullptr, 5), 0); - DN_UT_Assert(&result, str_result.success); - DN_UT_Assert(&result, str_result.value == 0); - } - + // NOTE: DN_I64FromStr8 for (DN_UT_Test(&result, "To I64: Convert empty string")) { - DN_Str8ToI64Result str_result = DN_Str8_ToI64(DN_STR8(""), 0); + DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit(""), 0); DN_UT_Assert(&result, str_result.success); DN_UT_Assert(&result, str_result.value == 0); } for (DN_UT_Test(&result, "To I64: Convert \"1\"")) { - DN_Str8ToI64Result str_result = DN_Str8_ToI64(DN_STR8("1"), 0); + DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1"), 0); DN_UT_Assert(&result, str_result.success); DN_UT_Assert(&result, str_result.value == 1); } for (DN_UT_Test(&result, "To I64: Convert \"-0\"")) { - DN_Str8ToI64Result str_result = DN_Str8_ToI64(DN_STR8("-0"), 0); + DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("-0"), 0); DN_UT_Assert(&result, str_result.success); DN_UT_Assert(&result, str_result.value == 0); } for (DN_UT_Test(&result, "To I64: Convert \"-1\"")) { - DN_Str8ToI64Result str_result = DN_Str8_ToI64(DN_STR8("-1"), 0); + DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("-1"), 0); DN_UT_Assert(&result, str_result.success); DN_UT_Assert(&result, str_result.value == -1); } for (DN_UT_Test(&result, "To I64: Convert \"1.2\"")) { - DN_Str8ToI64Result str_result = DN_Str8_ToI64(DN_STR8("1.2"), 0); + DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1.2"), 0); DN_UT_Assert(&result, !str_result.success); DN_UT_Assert(&result, str_result.value == 1); } for (DN_UT_Test(&result, "To I64: Convert \"1,234\"")) { - DN_Str8ToI64Result str_result = DN_Str8_ToI64(DN_STR8("1,234"), ','); + DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1,234"), ','); DN_UT_Assert(&result, str_result.success); DN_UT_Assert(&result, str_result.value == 1234); } for (DN_UT_Test(&result, "To I64: Convert \"1,2\"")) { - DN_Str8ToI64Result str_result = DN_Str8_ToI64(DN_STR8("1,2"), ','); + DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("1,2"), ','); DN_UT_Assert(&result, str_result.success); DN_UT_Assert(&result, str_result.value == 12); } for (DN_UT_Test(&result, "To I64: Convert \"12a3\"")) { - DN_Str8ToI64Result str_result = DN_Str8_ToI64(DN_STR8("12a3"), 0); + DN_I64FromResult str_result = DN_I64FromStr8(DN_Str8Lit("12a3"), 0); DN_UT_Assert(&result, !str_result.success); DN_UT_Assert(&result, str_result.value == 12); } - // NOTE: DN_Str8_ToU64 ///////////////////////////////////////////////////////////////////////// - for (DN_UT_Test(&result, "To U64: Convert nullptr")) { - DN_Str8ToU64Result str_result = DN_Str8_ToU64(DN_Str8_Init(nullptr, 5), 0); - DN_UT_Assert(&result, str_result.success); - DN_UT_AssertF(&result, str_result.value == 0, "result: %" PRIu64, str_result.value); - } - + // NOTE: DN_U64FromStr8 for (DN_UT_Test(&result, "To U64: Convert empty string")) { - DN_Str8ToU64Result str_result = DN_Str8_ToU64(DN_STR8(""), 0); + DN_U64FromResult str_result = DN_U64FromStr8(DN_Str8Lit(""), 0); DN_UT_Assert(&result, str_result.success); DN_UT_AssertF(&result, str_result.value == 0, "result: %" PRIu64, str_result.value); } for (DN_UT_Test(&result, "To U64: Convert \"1\"")) { - DN_Str8ToU64Result str_result = DN_Str8_ToU64(DN_STR8("1"), 0); + DN_U64FromResult str_result = DN_U64FromStr8(DN_Str8Lit("1"), 0); DN_UT_Assert(&result, str_result.success); DN_UT_AssertF(&result, str_result.value == 1, "result: %" PRIu64, str_result.value); } for (DN_UT_Test(&result, "To U64: Convert \"-0\"")) { - DN_Str8ToU64Result str_result = DN_Str8_ToU64(DN_STR8("-0"), 0); + DN_U64FromResult str_result = DN_U64FromStr8(DN_Str8Lit("-0"), 0); DN_UT_Assert(&result, !str_result.success); DN_UT_AssertF(&result, str_result.value == 0, "result: %" PRIu64, str_result.value); } for (DN_UT_Test(&result, "To U64: Convert \"-1\"")) { - DN_Str8ToU64Result str_result = DN_Str8_ToU64(DN_STR8("-1"), 0); + DN_U64FromResult str_result = DN_U64FromStr8(DN_Str8Lit("-1"), 0); DN_UT_Assert(&result, !str_result.success); DN_UT_AssertF(&result, str_result.value == 0, "result: %" PRIu64, str_result.value); } for (DN_UT_Test(&result, "To U64: Convert \"1.2\"")) { - DN_Str8ToU64Result str_result = DN_Str8_ToU64(DN_STR8("1.2"), 0); + DN_U64FromResult str_result = DN_U64FromStr8(DN_Str8Lit("1.2"), 0); DN_UT_Assert(&result, !str_result.success); DN_UT_AssertF(&result, str_result.value == 1, "result: %" PRIu64, str_result.value); } for (DN_UT_Test(&result, "To U64: Convert \"1,234\"")) { - DN_Str8ToU64Result str_result = DN_Str8_ToU64(DN_STR8("1,234"), ','); + DN_U64FromResult str_result = DN_U64FromStr8(DN_Str8Lit("1,234"), ','); DN_UT_Assert(&result, str_result.success); DN_UT_AssertF(&result, str_result.value == 1234, "result: %" PRIu64, str_result.value); } for (DN_UT_Test(&result, "To U64: Convert \"1,2\"")) { - DN_Str8ToU64Result str_result = DN_Str8_ToU64(DN_STR8("1,2"), ','); + DN_U64FromResult str_result = DN_U64FromStr8(DN_Str8Lit("1,2"), ','); DN_UT_Assert(&result, str_result.success); DN_UT_AssertF(&result, str_result.value == 12, "result: %" PRIu64, str_result.value); } for (DN_UT_Test(&result, "To U64: Convert \"12a3\"")) { - DN_Str8ToU64Result str_result = DN_Str8_ToU64(DN_STR8("12a3"), 0); + DN_U64FromResult str_result = DN_U64FromStr8(DN_Str8Lit("12a3"), 0); DN_UT_Assert(&result, !str_result.success); DN_UT_AssertF(&result, str_result.value == 12, "result: %" PRIu64, str_result.value); } - // NOTE: DN_Str8_Find ///////////////////////////////////////////////////////////////////// + // NOTE: DN_Str8Find for (DN_UT_Test(&result, "Find: String (char) is not in buffer")) { - DN_Str8 buf = DN_STR8("836a35becd4e74b66a0d6844d51f1a63018c7ebc44cf7e109e8e4bba57eefb55"); - DN_Str8 find = DN_STR8("2"); - DN_Str8FindResult str_result = DN_Str8_FindStr8(buf, find, DN_Str8EqCase_Sensitive); + DN_Str8 buf = DN_Str8Lit("836a35becd4e74b66a0d6844d51f1a63018c7ebc44cf7e109e8e4bba57eefb55"); + DN_Str8 find = DN_Str8Lit("2"); + DN_Str8FindResult str_result = DN_Str8FindStr8(buf, find, DN_Str8EqCase_Sensitive); DN_UT_Assert(&result, !str_result.found); DN_UT_Assert(&result, str_result.index == 0); DN_UT_Assert(&result, str_result.match.data == nullptr); @@ -2332,33 +2351,33 @@ static DN_UTCore DN_Tests_Str8() } for (DN_UT_Test(&result, "Find: String (char) is in buffer")) { - DN_Str8 buf = DN_STR8("836a35becd4e74b66a0d6844d51f1a63018c7ebc44cf7e109e8e4bba57eefb55"); - DN_Str8 find = DN_STR8("6"); - DN_Str8FindResult str_result = DN_Str8_FindStr8(buf, find, DN_Str8EqCase_Sensitive); + DN_Str8 buf = DN_Str8Lit("836a35becd4e74b66a0d6844d51f1a63018c7ebc44cf7e109e8e4bba57eefb55"); + DN_Str8 find = DN_Str8Lit("6"); + DN_Str8FindResult str_result = DN_Str8FindStr8(buf, find, DN_Str8EqCase_Sensitive); DN_UT_Assert(&result, str_result.found); DN_UT_Assert(&result, str_result.index == 2); DN_UT_Assert(&result, str_result.match.data[0] == '6'); } - // NOTE: DN_Str8_FileNameFromPath ////////////////////////////////////////////////////////////// + // NOTE: DN_Str8FileNameFromPath for (DN_UT_Test(&result, "File name from Windows path")) { - DN_Str8 buf = DN_STR8("C:\\ABC\\str_result.exe"); - DN_Str8 str_result = DN_Str8_FileNameFromPath(buf); - DN_UT_AssertF(&result, str_result == DN_STR8("str_result.exe"), "%.*s", DN_STR_FMT(str_result)); + DN_Str8 buf = DN_Str8Lit("C:\\ABC\\str_result.exe"); + DN_Str8 str_result = DN_Str8FileNameFromPath(buf); + DN_UT_AssertF(&result, DN_Str8Eq(str_result, DN_Str8Lit("str_result.exe")), "%.*s", DN_Str8PrintFmt(str_result)); } for (DN_UT_Test(&result, "File name from Linux path")) { - DN_Str8 buf = DN_STR8("/ABC/str_result.exe"); - DN_Str8 str_result = DN_Str8_FileNameFromPath(buf); - DN_UT_AssertF(&result, str_result == DN_STR8("str_result.exe"), "%.*s", DN_STR_FMT(str_result)); + DN_Str8 buf = DN_Str8Lit("/ABC/str_result.exe"); + DN_Str8 str_result = DN_Str8FileNameFromPath(buf); + DN_UT_AssertF(&result, DN_Str8Eq(str_result, DN_Str8Lit("str_result.exe")), "%.*s", DN_Str8PrintFmt(str_result)); } - // NOTE: DN_Str8_TrimPrefix //////////////////////////////////////////////////////////////////// + // NOTE: DN_Str8TrimPrefix for (DN_UT_Test(&result, "Trim prefix")) { - DN_Str8 prefix = DN_STR8("@123"); - DN_Str8 buf = DN_STR8("@123string"); - DN_Str8 str_result = DN_Str8_TrimPrefix(buf, prefix, DN_Str8EqCase_Sensitive); - DN_UT_Assert(&result, str_result == DN_STR8("string")); + DN_Str8 prefix = DN_Str8Lit("@123"); + DN_Str8 buf = DN_Str8Lit("@123string"); + DN_Str8 str_result = DN_Str8TrimPrefix(buf, prefix, DN_Str8EqCase_Sensitive); + DN_UT_Assert(&result, DN_Str8Eq(str_result, DN_Str8Lit("string"))); } } return result; @@ -2383,8 +2402,8 @@ static DN_UTCore DN_Tests_TicketMutex() DN_TicketMutex mutex = {}; unsigned int ticket_a = DN_TicketMutex_MakeTicket(&mutex); unsigned int ticket_b = DN_TicketMutex_MakeTicket(&mutex); - DN_UT_Assert(&result, DN_CAST(bool) DN_TicketMutex_CanLock(&mutex, ticket_b) == false); - DN_UT_Assert(&result, DN_CAST(bool) DN_TicketMutex_CanLock(&mutex, ticket_a) == true); + DN_UT_Assert(&result, DN_Cast(bool) DN_TicketMutex_CanLock(&mutex, ticket_b) == false); + DN_UT_Assert(&result, DN_Cast(bool) DN_TicketMutex_CanLock(&mutex, ticket_a) == true); DN_TicketMutex_BeginTicket(&mutex, ticket_a); DN_TicketMutex_End(&mutex); @@ -2405,22 +2424,22 @@ static DN_UTCore DN_Tests_Win() DN_UT_LogF(&result, "OS Win32\n"); { DN_OSTLSTMem tmem = DN_OS_TLSTMem(nullptr); - DN_Str8 input8 = DN_STR8("String"); + DN_Str8 input8 = DN_Str8Lit("String"); DN_Str16 input16 = DN_Str16{(wchar_t *)(L"String"), sizeof(L"String") / sizeof(L"String"[0]) - 1}; for (DN_UT_Test(&result, "Str8 to Str16")) { DN_Str16 str_result = DN_W32_Str8ToStr16(tmem.arena, input8); - DN_UT_Assert(&result, str_result == input16); + DN_UT_Assert(&result, DN_Str16Eq(str_result, input16)); } for (DN_UT_Test(&result, "Str16 to Str8")) { DN_Str8 str_result = DN_W32_Str16ToStr8(tmem.arena, input16); - DN_UT_Assert(&result, str_result == input8); + DN_UT_Assert(&result, DN_Str8Eq(str_result, input8)); } for (DN_UT_Test(&result, "Str16 to Str8: Null terminates string")) { int size_required = DN_W32_Str16ToStr8Buffer(input16, nullptr, 0); - char *string = DN_Arena_NewArray(tmem.arena, char, size_required + 1, DN_ZeroMem_No); + char *string = DN_ArenaNewArray(tmem.arena, char, size_required + 1, DN_ZMem_No); // Fill the string with error sentinels DN_Memset(string, 'Z', size_required + 1); @@ -2438,8 +2457,8 @@ static DN_UTCore DN_Tests_Win() int size_returned = DN_W32_Str16ToStr8Buffer(input16, nullptr, 0); char const EXPECTED[] = {'S', 't', 'r', 'i', 'n', 'g', 0}; - DN_UT_AssertF(&result, DN_CAST(int) string8.size == size_returned, "string_size: %d, result: %d", DN_CAST(int) string8.size, size_returned); - DN_UT_AssertF(&result, DN_CAST(int) string8.size == DN_ArrayCountU(EXPECTED) - 1, "string_size: %d, expected: %zu", DN_CAST(int) string8.size, DN_ArrayCountU(EXPECTED) - 1); + DN_UT_AssertF(&result, DN_Cast(int) string8.size == size_returned, "string_size: %d, result: %d", DN_Cast(int) string8.size, size_returned); + DN_UT_AssertF(&result, DN_Cast(int) string8.size == DN_ArrayCountU(EXPECTED) - 1, "string_size: %d, expected: %zu", DN_Cast(int) string8.size, DN_ArrayCountU(EXPECTED) - 1); DN_UT_Assert(&result, DN_Memcmp(EXPECTED, string8.data, sizeof(EXPECTED)) == 0); } } diff --git a/Source/Extra/dn_type_info.cpp b/Source/Extra/dn_type_info.cpp index f87f4d8..413b764 100644 --- a/Source/Extra/dn_type_info.cpp +++ b/Source/Extra/dn_type_info.cpp @@ -25,7 +25,7 @@ DN_TypeGetField DN_Type_GetField(DN_TypeInfo const *type_info, DN_Str8 name) if (type_field->name == name) { result.success = true; result.index = index; - result.field = DN_CAST(DN_TypeField *)type_field; + result.field = DN_Cast(DN_TypeField *)type_field; break; } } diff --git a/Source/OS/dn_os.cpp b/Source/OS/dn_os.cpp index a9e3379..ce8b9ee 100644 --- a/Source/OS/dn_os.cpp +++ b/Source/OS/dn_os.cpp @@ -13,7 +13,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); @@ -71,17 +71,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); } @@ -114,24 +114,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 @@ -142,7 +142,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 } @@ -163,7 +163,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_); @@ -182,7 +182,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; } @@ -223,29 +223,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, @@ -254,7 +281,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, @@ -300,9 +327,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; } @@ -311,7 +338,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; } @@ -319,7 +346,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; } @@ -327,7 +354,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; } @@ -335,7 +362,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; } @@ -415,9 +442,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; } @@ -452,24 +479,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; } @@ -478,10 +505,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 = {}; } @@ -519,7 +546,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; } @@ -536,7 +563,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)) @@ -549,7 +576,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; } @@ -564,26 +591,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; @@ -619,8 +646,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; } @@ -628,7 +655,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; @@ -668,7 +695,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; @@ -685,7 +712,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; @@ -699,7 +726,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) { @@ -750,7 +777,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); @@ -760,7 +787,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; diff --git a/Source/OS/dn_os.h b/Source/OS/dn_os.h index c13ce33..4e21738 100644 --- a/Source/OS/dn_os.h +++ b/Source/OS/dn_os.h @@ -124,7 +124,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 @@ -208,7 +208,7 @@ struct DN_OSConditionVariable DN_U64 handle; }; -// NOTE: DN_OSThread /////////////////////////////////////////////////////////////////////////////// +// NOTE: DN_OSThread typedef DN_I32(DN_OSThreadFunc)(struct DN_OSThread *); struct DN_OSThread @@ -223,7 +223,7 @@ struct DN_OSThread DN_OSSemaphore init_semaphore; }; -// NOTE: DN_OSHttp ///////////////////////////////////////////////////////////////////////////////// +// NOTE: DN_OSHttp enum DN_OSHttpRequestSecure { DN_OSHttpRequestSecure_No, @@ -309,13 +309,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 (); @@ -409,8 +414,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); diff --git a/Source/OS/dn_os_allocator.cpp b/Source/OS/dn_os_allocator.cpp index bf44b5f..eeda1a4 100644 --- a/Source/OS/dn_os_allocator.cpp +++ b/Source/OS/dn_os_allocator.cpp @@ -3,23 +3,23 @@ #include "../dn_base_inc.h" #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; @@ -27,7 +27,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; } diff --git a/Source/OS/dn_os_allocator.h b/Source/OS/dn_os_allocator.h index b1b5532..84ddc64 100644 --- a/Source/OS/dn_os_allocator.h +++ b/Source/OS/dn_os_allocator.h @@ -1,7 +1,7 @@ #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) diff --git a/Source/OS/dn_os_containers.cpp b/Source/OS/dn_os_containers.cpp index 2110e01..11d7919 100644 --- a/Source/OS/dn_os_containers.cpp +++ b/Source/OS/dn_os_containers.cpp @@ -22,7 +22,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; @@ -80,7 +80,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; @@ -101,7 +101,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; @@ -115,15 +115,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; } @@ -177,10 +177,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; } diff --git a/Source/OS/dn_os_containers.h b/Source/OS/dn_os_containers.h index 17ad48a..104c943 100644 --- a/Source/OS/dn_os_containers.h +++ b/Source/OS/dn_os_containers.h @@ -30,8 +30,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); @@ -43,5 +43,5 @@ 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) diff --git a/Source/OS/dn_os_posix.cpp b/Source/OS/dn_os_posix.cpp index 4ef47c1..b113f4e 100644 --- a/Source/OS/dn_os_posix.cpp +++ b/Source/OS/dn_os_posix.cpp @@ -65,10 +65,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( @@ -80,9 +80,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; } @@ -113,9 +113,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; } @@ -150,7 +150,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; @@ -196,7 +196,7 @@ DN_API DN_OSDiskSpace DN_OS_DiskSpace(DN_Str8 path) { DN_OSTLSTMem tmem = DN_OS_TLSPushTMem(nullptr); DN_OSDiskSpace result = {}; - DN_Str8 path_z_terminated = DN_Str8_FromStr8(tmem.arena, path); + DN_Str8 path_z_terminated = DN_Str8FromStr8(tmem.arena, path); struct statvfs info = {}; if (statvfs(path_z_terminated.data, &info) != 0) @@ -217,7 +217,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 @@ -245,9 +245,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); @@ -255,9 +255,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; @@ -284,7 +284,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; } @@ -293,7 +293,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; } @@ -309,7 +309,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; @@ -326,7 +326,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; @@ -343,7 +343,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; @@ -354,16 +354,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)); } @@ -392,7 +392,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)); } @@ -406,7 +406,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))) { @@ -420,7 +420,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; } @@ -444,7 +444,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; } @@ -480,10 +480,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; } @@ -497,12 +497,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; } @@ -510,7 +510,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; @@ -528,14 +528,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; @@ -559,7 +559,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; } @@ -567,7 +567,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; @@ -579,7 +579,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; @@ -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_Str8_FromStr8(tmem.arena, path); + DN_Str8 copy = DN_Str8FromStr8(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]; @@ -626,7 +626,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; } } } @@ -654,23 +654,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; @@ -679,7 +679,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_ @@ -757,30 +757,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); } } @@ -803,7 +803,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] = {}; @@ -815,7 +815,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; } @@ -842,7 +842,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; } @@ -865,7 +865,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; } @@ -878,7 +878,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; } @@ -890,27 +890,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_Str8FromStr8(tmem.arena, arg).data; // NOTE: Copy string to guarantee it is null-terminated } // NOTE: Change the working directory if there is one @@ -928,14 +928,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_Str8FromStr8(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; } @@ -949,7 +949,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; } @@ -1016,7 +1016,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); @@ -1272,7 +1272,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) @@ -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_Str8_FromStr8(tmem.arena, name); + DN_Str8 copy = DN_Str8FromStr8(tmem.arena, name); pthread_t thread = pthread_self(); pthread_setname_np(thread, (char *)copy.data); #endif @@ -1313,49 +1313,49 @@ 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); + } 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_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); + } 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_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); + } 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_Assert(to_u64.success); } @@ -1411,12 +1411,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); @@ -1426,12 +1426,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); @@ -1467,15 +1467,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; } @@ -1489,11 +1489,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) @@ -1511,7 +1511,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 = {}; } diff --git a/Source/OS/dn_os_print.cpp b/Source/OS/dn_os_print.cpp index 6050902..1c88e01 100644 --- a/Source/OS/dn_os_print.cpp +++ b/Source/OS/dn_os_print.cpp @@ -57,15 +57,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 } @@ -91,20 +91,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; } @@ -113,7 +113,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) @@ -122,17 +122,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, ...) @@ -146,13 +146,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, ...) @@ -166,5 +166,5 @@ 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")); } diff --git a/Source/OS/dn_os_string.cpp b/Source/OS/dn_os_string.cpp index 844953f..86ccf2c 100644 --- a/Source/OS/dn_os_string.cpp +++ b/Source/OS/dn_os_string.cpp @@ -3,230 +3,227 @@ #include "../dn_base_inc.h" #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, @@ -235,19 +232,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) { @@ -255,43 +252,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; diff --git a/Source/OS/dn_os_string.h b/Source/OS/dn_os_string.h index 711741f..cf6be92 100644 --- a/Source/OS/dn_os_string.h +++ b/Source/OS/dn_os_string.h @@ -6,69 +6,69 @@ // 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) diff --git a/Source/OS/dn_os_tls.cpp b/Source/OS/dn_os_tls.cpp index 0a4a827..3bf6717 100644 --- a/Source/OS/dn_os_tls.cpp +++ b/Source/OS/dn_os_tls.cpp @@ -5,7 +5,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) @@ -15,7 +15,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(); @@ -37,9 +37,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; } } @@ -55,7 +55,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; @@ -163,22 +163,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 } @@ -190,7 +190,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--; } @@ -221,8 +221,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) @@ -234,36 +234,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)); } } } @@ -280,16 +280,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; } @@ -310,20 +310,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; @@ -333,7 +333,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; } @@ -343,7 +343,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; @@ -373,9 +373,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); diff --git a/Source/OS/dn_os_w32.cpp b/Source/OS/dn_os_w32.cpp index fa7ca81..aa6a936 100644 --- a/Source/OS/dn_os_w32.cpp +++ b/Source/OS/dn_os_w32.cpp @@ -94,8 +94,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); @@ -108,11 +108,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); @@ -131,12 +131,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; } @@ -214,22 +214,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); @@ -284,7 +284,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; @@ -322,10 +322,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; } @@ -347,10 +347,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; } @@ -358,7 +358,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)) { @@ -401,7 +401,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; } @@ -417,24 +417,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; } @@ -445,9 +445,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; } @@ -462,9 +462,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; @@ -473,8 +473,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; } @@ -484,14 +484,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) @@ -505,7 +505,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); @@ -521,7 +521,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; @@ -538,7 +538,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); @@ -554,7 +554,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); @@ -571,7 +571,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); @@ -639,7 +639,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); @@ -648,10 +648,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) { @@ -659,9 +659,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); @@ -673,7 +673,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; @@ -683,7 +683,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, @@ -734,7 +734,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 @@ -746,7 +746,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; @@ -760,7 +760,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; @@ -779,7 +779,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 /////////////////////////////////////////////////////////////////////////////// @@ -790,8 +790,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; } @@ -827,17 +827,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; } @@ -849,16 +849,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); @@ -887,8 +887,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; } @@ -899,8 +899,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; } } @@ -928,8 +928,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; } @@ -940,8 +940,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; } } @@ -971,8 +971,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; } @@ -992,7 +992,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; } @@ -1023,7 +1023,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); @@ -1164,7 +1164,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; } @@ -1248,7 +1248,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 @@ -1258,7 +1258,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; } @@ -1275,7 +1275,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; @@ -1291,7 +1291,7 @@ DN_API void DN_W32_ThreadSetName(DN_Str8 name) } DN_MSVC_WARNING_POP - DN_Arena_TempMemEnd(tmem); + DN_ArenaTempMemEnd(tmem); } // NOTE: DN_OSHttp ///////////////////////////////////////////////////////////////////////////////// @@ -1300,8 +1300,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); @@ -1331,7 +1331,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 @@ -1343,7 +1343,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 { @@ -1353,17 +1353,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); @@ -1375,7 +1375,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); @@ -1433,9 +1433,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; } @@ -1465,11 +1465,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; } @@ -1486,7 +1486,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 = {}; @@ -1569,11 +1569,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(); } @@ -1581,18 +1581,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; @@ -1604,14 +1604,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; } @@ -1620,7 +1620,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); @@ -1631,7 +1631,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; } @@ -1639,7 +1639,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); @@ -1653,11 +1653,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; @@ -1670,7 +1670,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); @@ -1683,11 +1683,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; @@ -1708,17 +1708,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; @@ -1734,17 +1734,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; @@ -1768,9 +1768,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; @@ -1780,7 +1780,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; @@ -1790,7 +1790,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; } @@ -1821,7 +1821,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; diff --git a/Source/SIMD/dn_simd_avx512f.cpp b/Source/SIMD/dn_simd_avx512f.cpp index 07a8794..e8a71c7 100644 --- a/Source/SIMD/dn_simd_avx512f.cpp +++ b/Source/SIMD/dn_simd_avx512f.cpp @@ -6,7 +6,7 @@ DN_API DN_Str8FindResult DN_SIMD_Str8FindAVX512F(DN_Str8 string, DN_Str8 find) { // NOTE: Algorithm as described in http://0x80.pl/articles/simd-strfind.html DN_Str8FindResult result = {}; - if (!DN_Str8_HasData(string) || !DN_Str8_HasData(find) || find.size > string.size) + if (string.size == 0 || find.size == 0 || find.size > string.size) return result; __m512i const find_first_ch = _mm512_set1_epi8(find.data[0]); @@ -77,10 +77,10 @@ DN_API DN_Str8FindResult DN_SIMD_Str8FindAVX512F(DN_Str8 string, DN_Str8 find) } if (result.found) { - result.start_to_before_match = DN_Str8_Init(string.data, result.index); - result.match = DN_Str8_Init(string.data + result.index, find.size); - result.match_to_end_of_buffer = DN_Str8_Init(result.match.data, string.size - result.index); - result.after_match_to_end_of_buffer = DN_Str8_Advance(result.match_to_end_of_buffer, find.size); + result.start_to_before_match = DN_Str8FromPtr(string.data, result.index); + result.match = DN_Str8FromPtr(string.data + result.index, find.size); + result.match_to_end_of_buffer = DN_Str8FromPtr(result.match.data, string.size - result.index); + result.after_match_to_end_of_buffer = DN_Str8Advance(result.match_to_end_of_buffer, find.size); return result; } @@ -91,14 +91,14 @@ DN_API DN_Str8FindResult DN_SIMD_Str8FindAVX512F(DN_Str8 string, DN_Str8 find) } for (DN_USize index = ptr - string.data; index < string.size; index++) { - DN_Str8 string_slice = DN_Str8_Slice(string, index, find.size); - if (DN_Str8_Eq(string_slice, find)) { + DN_Str8 string_slice = DN_Str8Slice(string, index, find.size); + if (DN_Str8Eq(string_slice, find)) { 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.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.size); + result.start_to_before_match = DN_Str8FromPtr(string.data, index); + result.match = DN_Str8FromPtr(string.data + index, find.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.size); return result; } } @@ -110,7 +110,7 @@ DN_API DN_Str8FindResult DN_SIMD_Str8FindLastAVX512F(DN_Str8 string, DN_Str8 fin { // NOTE: Algorithm as described in http://0x80.pl/articles/simd-strfind.html DN_Str8FindResult result = {}; - if (!DN_Str8_HasData(string) || !DN_Str8_HasData(find) || find.size > string.size) + if (string.size == 0 || find.size == 0 || find.size > string.size) return result; __m512i const find_first_ch = _mm512_set1_epi8(find.data[0]); @@ -182,9 +182,9 @@ DN_API DN_Str8FindResult DN_SIMD_Str8FindLastAVX512F(DN_Str8 string, DN_Str8 fin } if (result.found) { - result.start_to_before_match = DN_Str8_Init(string.data, result.index); - result.match = DN_Str8_Init(string.data + result.index, find.size); - result.match_to_end_of_buffer = DN_Str8_Init(result.match.data, string.size - result.index); + result.start_to_before_match = DN_Str8FromPtr(string.data, result.index); + result.match = DN_Str8FromPtr(string.data + result.index, find.size); + result.match_to_end_of_buffer = DN_Str8FromPtr(result.match.data, string.size - result.index); return result; } @@ -193,13 +193,13 @@ DN_API DN_Str8FindResult DN_SIMD_Str8FindLastAVX512F(DN_Str8 string, DN_Str8 fin } for (DN_USize index = ptr - string.data - 1; index < string.size; index--) { - DN_Str8 string_slice = DN_Str8_Slice(string, index, find.size); - if (DN_Str8_Eq(string_slice, find)) { + DN_Str8 string_slice = DN_Str8Slice(string, index, find.size); + if (DN_Str8Eq(string_slice, find)) { 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.size); - result.match_to_end_of_buffer = DN_Str8_Init(result.match.data, string.size - index); + result.start_to_before_match = DN_Str8FromPtr(string.data, index); + result.match = DN_Str8FromPtr(string.data + index, find.size); + result.match_to_end_of_buffer = DN_Str8FromPtr(result.match.data, string.size - index); return result; } } @@ -214,7 +214,7 @@ DN_API DN_Str8BSplitResult DN_SIMD_Str8BSplitAVX512F(DN_Str8 string, DN_Str8 fin if (find_result.found) { result.lhs.data = string.data; result.lhs.size = find_result.index; - result.rhs = DN_Str8_Advance(find_result.match_to_end_of_buffer, find.size); + result.rhs = DN_Str8Advance(find_result.match_to_end_of_buffer, find.size); } else { result.lhs = string; } @@ -229,7 +229,7 @@ DN_API DN_Str8BSplitResult DN_SIMD_Str8BSplitLastAVX512F(DN_Str8 string, DN_Str8 if (find_result.found) { result.lhs.data = string.data; result.lhs.size = find_result.index; - result.rhs = DN_Str8_Advance(find_result.match_to_end_of_buffer, find.size); + result.rhs = DN_Str8Advance(find_result.match_to_end_of_buffer, find.size); } else { result.lhs = string; } @@ -240,7 +240,7 @@ DN_API DN_Str8BSplitResult DN_SIMD_Str8BSplitLastAVX512F(DN_Str8 string, DN_Str8 DN_API DN_USize DN_SIMD_Str8SplitAVX512F(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) + if (string.size == 0 || delimiter.size == 0 || delimiter.size <= 0) return result; DN_Str8BSplitResult split = {}; @@ -262,7 +262,7 @@ DN_API DN_Slice DN_SIMD_Str8SplitAllocAVX512F(DN_Arena *arena, DN_Str8 { DN_Slice result = {}; DN_USize splits_required = DN_SIMD_Str8SplitAVX512F(string, delimiter, /*splits*/ nullptr, /*count*/ 0, mode); - result.data = DN_Arena_NewArray(arena, DN_Str8, splits_required, DN_ZeroMem_No); + result.data = DN_ArenaNewArray(arena, DN_Str8, splits_required, DN_ZMem_No); if (result.data) { result.size = DN_SIMD_Str8SplitAVX512F(string, delimiter, result.data, splits_required, mode); DN_Assert(splits_required == result.size); diff --git a/Source/SIMD/dn_simd_avx512f.h b/Source/SIMD/dn_simd_avx512f.h index 73e7a98..2930949 100644 --- a/Source/SIMD/dn_simd_avx512f.h +++ b/Source/SIMD/dn_simd_avx512f.h @@ -18,11 +18,11 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// */ -DN_API DN_Str8FindResult DN_Str8_FindStr8AVX512F (DN_Str8 string, DN_Str8 find); -DN_API DN_Str8FindResult DN_Str8_FindLastStr8AVX512F (DN_Str8 string, DN_Str8 find); -DN_API DN_Str8BSplitResult DN_Str8_BSplitAVX512F (DN_Str8 string, DN_Str8 find); -DN_API DN_Str8BSplitResult DN_Str8_BSplitLastAVX512F(DN_Str8 string, DN_Str8 find); -DN_API DN_USize DN_Str8_SplitAVX512F (DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_USize splits_count, DN_Str8SplitIncludeEmptyStrings mode); -DN_API DN_Slice DN_Str8_SplitAllocAVX512F (DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode); +DN_API DN_Str8FindResult DN_Str8FindStr8AVX512F (DN_Str8 string, DN_Str8 find); +DN_API DN_Str8FindResult DN_Str8FindLastStr8AVX512F (DN_Str8 string, DN_Str8 find); +DN_API DN_Str8BSplitResult DN_Str8BSplitAVX512F (DN_Str8 string, DN_Str8 find); +DN_API DN_Str8BSplitResult DN_Str8BSplitLastAVX512F(DN_Str8 string, DN_Str8 find); +DN_API DN_USize DN_Str8SplitAVX512F (DN_Str8 string, DN_Str8 delimiter, DN_Str8 *splits, DN_USize splits_count, DN_Str8SplitIncludeEmptyStrings mode); +DN_API DN_Slice DN_Str8SplitAllocAVX512F (DN_Arena *arena, DN_Str8 string, DN_Str8 delimiter, DN_Str8SplitIncludeEmptyStrings mode); #endif // DN_SIMD_AVX512F_H diff --git a/Source/Standalone/dn_ini.c b/Source/Standalone/dn_ini.c index 5fd0c34..af3dc4b 100644 --- a/Source/Standalone/dn_ini.c +++ b/Source/Standalone/dn_ini.c @@ -4,17 +4,20 @@ #include #endif -#include - -typedef struct DN_INIArena { - char *base; - size_t used, max; -} DN_INIArena; - -typedef struct DN_INIStr8BSplit { +typedef struct DN_INIStr8BSplit DN_INIStr8BSplit; +struct DN_INIStr8BSplit { DN_INIStr8 lhs; DN_INIStr8 rhs; -} DN_INIStr8BSplit; +}; + +typedef struct DN_INIStr8Builder DN_INIStr8Builder; +struct DN_INIStr8Builder +{ + char *data; + size_t used; + size_t max; + size_t size_req; +}; void *DN_INI_ArenaAlloc(DN_INIArena *arena, size_t size) { @@ -34,7 +37,7 @@ static bool DN_INI_CharIsWhitespace_(char ch) return result; } -static DN_INIStr8 DN_INI_Str8FromPtr(char const *data, uint32_t count) +DN_INIStr8 DN_INI_Str8FromPtr(char const *data, size_t count) { DN_INIStr8 result = {}; result.data = (char *)data; @@ -48,13 +51,13 @@ static bool DN_INI_Str8Eq(DN_INIStr8 lhs, DN_INIStr8 rhs) return result; } -static DN_INIStr8 DN_INI_Str8Slice(DN_INIStr8 slice, uint32_t offset, uint32_t size) +static DN_INIStr8 DN_INI_Str8Slice(DN_INIStr8 slice, size_t offset, size_t size) { DN_INIStr8 result = {}; if (slice.data) { - uint32_t max_offset = slice.size; - uint32_t final_offset = offset <= max_offset ? offset : max_offset; - uint32_t max_size = slice.size - final_offset; + size_t max_offset = slice.size; + size_t final_offset = offset <= max_offset ? offset : max_offset; + size_t max_size = slice.size - final_offset; result.data = slice.data + final_offset; result.size = size <= max_size ? size : max_size; } @@ -70,8 +73,8 @@ static DN_INIStr8BSplit DN_INI_Str8BSplit(DN_INIStr8 str8, DN_INIStr8 find) for (size_t index = 0; index < (str8.size - find.size) + 1; index++) { DN_INIStr8 slice = DN_INI_Str8FromPtr(str8.data + index, find.size); if (DN_INI_Str8Eq(slice, find)) { - result.lhs = DN_INI_Str8FromPtr(str8.data, (uint32_t)index); - uint32_t rhs_size = (uint32_t)(str8.size - (index + 1)); + result.lhs = DN_INI_Str8FromPtr(str8.data, (size_t)index); + size_t rhs_size = (size_t)(str8.size - (index + 1)); DN_INI_Assert(rhs_size < str8.size); result.rhs = DN_INI_Str8FromPtr(str8.data + index + 1, rhs_size); break; @@ -92,8 +95,8 @@ static DN_INIStr8BSplit DN_INI_Str8BSplitReverse(DN_INIStr8 str8, DN_INIStr8 fin for (size_t index = str8.size - find.size; index > 0; index--) { DN_INIStr8 slice = DN_INI_Str8FromPtr(str8.data + index, find.size); if (DN_INI_Str8Eq(slice, find)) { - result.lhs = DN_INI_Str8FromPtr(str8.data, (uint32_t)index); - uint32_t rhs_size = (uint32_t)(str8.size - index - find.size); + result.lhs = DN_INI_Str8FromPtr(str8.data, (size_t)index); + size_t rhs_size = (size_t)(str8.size - index - find.size); DN_INI_Assert(rhs_size < str8.size); result.rhs = DN_INI_Str8FromPtr(str8.data + index + find.size, rhs_size); break; @@ -105,7 +108,7 @@ static DN_INIStr8BSplit DN_INI_Str8BSplitReverse(DN_INIStr8 str8, DN_INIStr8 fin return result; } -DN_INITokeniser DN_INI_TokeniserFromPtr(char const *buf, uint32_t count) +DN_INITokeniser DN_INI_TokeniserFromPtr(char const *buf, size_t count) { DN_INITokeniser result = {}; result.data = (char *)buf; @@ -115,7 +118,7 @@ DN_INITokeniser DN_INI_TokeniserFromPtr(char const *buf, uint32_t count) DN_INIToken DN_INI_NextToken(DN_INITokeniser const *tokeniser) { - uint32_t pos = tokeniser->pos; + size_t pos = tokeniser->pos; DN_INIToken result = {}; result.line = tokeniser->line; result.line_start = tokeniser->line_start ? tokeniser->line_start : tokeniser->data; @@ -125,19 +128,19 @@ DN_INIToken DN_INI_NextToken(DN_INITokeniser const *tokeniser) if (tokeniser->pos < tokeniser->count && DN_INI_CharIsWhitespace_(tokeniser->data[pos])) { if (tokeniser->data[pos++] == '\n') { result.line++; - result.line_start = tokeniser->data + pos; - result.new_line = true; + result.line_start = tokeniser->data + pos; + result.line_start_new_line = true; } continue; } if (pos >= tokeniser->count) { - if (tokeniser->prev_token.type == DN_INITokenType_Nil || - tokeniser->prev_token.type == DN_INITokenType_Value || - tokeniser->prev_token.type == DN_INITokenType_Comment || - tokeniser->prev_token.type == DN_INITokenType_Value || - tokeniser->prev_token.type == DN_INITokenType_KeyValueSeparator || - tokeniser->prev_token.type == DN_INITokenType_MultilineValue || + if (tokeniser->prev_token.type == DN_INITokenType_Nil || + tokeniser->prev_token.type == DN_INITokenType_Value || + tokeniser->prev_token.type == DN_INITokenType_Comment || + tokeniser->prev_token.type == DN_INITokenType_Value || + tokeniser->prev_token.type == DN_INITokenType_FieldSeparator || + tokeniser->prev_token.type == DN_INITokenType_MultilineValue || tokeniser->prev_token.type == DN_INITokenType_Section) { result.type = DN_INITokenType_EndOfStream; } else { @@ -162,7 +165,7 @@ DN_INIToken DN_INI_NextToken(DN_INITokeniser const *tokeniser) result.type = DN_INITokenType_Section; result.next_p = pos + 1; } - result.count = (uint32_t)((tokeniser->data + pos) - result.data); + result.count = (size_t)((tokeniser->data + pos) - result.data); } } break; @@ -182,7 +185,7 @@ DN_INIToken DN_INI_NextToken(DN_INITokeniser const *tokeniser) pos++; if (pos >= tokeniser->count || tokeniser->data[pos] == '\n') { result.type = DN_INITokenType_Comment; - result.count = (uint32_t)((tokeniser->data + pos) - result.data); + result.count = (size_t)((tokeniser->data + pos) - result.data); result.next_p = pos; } } @@ -191,7 +194,7 @@ DN_INIToken DN_INI_NextToken(DN_INITokeniser const *tokeniser) case '=': { if (tokeniser->prev_token.type == DN_INITokenType_Key) { - result.type = DN_INITokenType_KeyValueSeparator; + result.type = DN_INITokenType_FieldSeparator; } else { result.type = DN_INITokenType_Error; result.error = DN_INIStr8Lit("Invalid key-value separator, '=' is not being used to separate a key-value pair"); @@ -211,37 +214,37 @@ DN_INIToken DN_INI_NextToken(DN_INITokeniser const *tokeniser) for (; result.type == DN_INITokenType_Nil; pos++) { bool end_of_stream = pos >= tokeniser->count; bool end_of_quote = !end_of_stream && quoted && tokeniser->data[pos] == '"'; + bool hash = tokeniser->data[pos] == '#' && !quoted; + bool backslash = tokeniser->data[pos] == '\\' && !quoted; + bool equals = tokeniser->data[pos] == '=' && !quoted; - if (end_of_stream || - DN_INI_CharIsWhitespace_(tokeniser->data[pos]) || - tokeniser->data[pos] == '#' || - tokeniser->data[pos] == '\\' || - tokeniser->data[pos] == '=' || - end_of_quote) { - - uint32_t next_p = pos; + if (end_of_stream || DN_INI_CharIsWhitespace_(tokeniser->data[pos]) || hash || backslash || equals || end_of_quote) { + result.count = (size_t)((tokeniser->data + pos) - result.data); + result.next_p = pos; if (end_of_quote) { - next_p = pos + 1; + result.next_p = pos + 1; DN_INI_Assert(!end_of_stream); DN_INI_Assert(tokeniser->data[pos] == '"'); } if (!end_of_stream && tokeniser->data[pos] == '\\') { - if (tokeniser->prev_token.type != DN_INITokenType_KeyValueSeparator && + if (tokeniser->prev_token.type != DN_INITokenType_FieldSeparator && tokeniser->prev_token.type != DN_INITokenType_Value && tokeniser->prev_token.type != DN_INITokenType_MultilineValue) { result.type = DN_INITokenType_Error; result.error = DN_INIStr8Lit("Invalid unquoted string, escape character '\\' is only allowed in INI values"); - result.count = (uint32_t)((tokeniser->data + pos) - result.data); - result.next_p = next_p; + result.count = (size_t)((tokeniser->data + pos) - result.data); break; } DN_INIStr8 esc_str8 = DN_INI_Str8Slice(DN_INI_Str8FromPtr(tokeniser->data, tokeniser->count), pos + 1, 1); - if (DN_INI_Str8Eq(esc_str8, DN_INIStr8Lit("\n"))) - next_p += 2; - else - next_p += 1; + if (DN_INI_Str8Eq(esc_str8, DN_INIStr8Lit("\n"))) { + result.next_p += 2; + } else if (DN_INI_Str8Eq(esc_str8, DN_INIStr8Lit("\\"))) { + // NOTE: Backespace is escaping a backspace + } else { + result.next_p += 1; + } } // NOTE: We only have a continuation of a multiline if we didn't have a newline, e.g.: @@ -254,12 +257,13 @@ DN_INIToken DN_INI_NextToken(DN_INITokeniser const *tokeniser) // 'next', the previous value is a multiline-value, but, we started a new-line which // terminates the multi-line value. This means that we know we're starting a new // key-value pair so we should _not_ append the multi-line value. - bool multiline_value = tokeniser->prev_token.type == DN_INITokenType_MultilineValue && !result.new_line; + bool multiline_value = tokeniser->prev_token.type == DN_INITokenType_MultilineValue && !result.line_start_new_line; + bool value = tokeniser->prev_token.type == DN_INITokenType_Value && !result.line_start_new_line; - if (tokeniser->prev_token.type == DN_INITokenType_KeyValueSeparator || multiline_value || tokeniser->prev_token.type == DN_INITokenType_Value) { + if (tokeniser->prev_token.type == DN_INITokenType_FieldSeparator || multiline_value || value) { if (tokeniser->data[pos] == ' ') // Value can have spaces in it without quotes continue; - result.type = tokeniser->prev_token.type == DN_INITokenType_KeyValueSeparator ? DN_INITokenType_Value : DN_INITokenType_MultilineValue; + result.type = tokeniser->prev_token.type == DN_INITokenType_FieldSeparator ? DN_INITokenType_Value : DN_INITokenType_MultilineValue; } else if (tokeniser->prev_token.type == DN_INITokenType_Key) { result.type = DN_INITokenType_Error; result.error = DN_INIStr8Lit("Invalid unquoted string, multiple consecutive keys encountered"); @@ -267,9 +271,6 @@ DN_INIToken DN_INI_NextToken(DN_INITokeniser const *tokeniser) result.type = DN_INITokenType_Key; } - result.count = (uint32_t)((tokeniser->data + pos) - result.data); - result.next_p = next_p; - if (result.type == DN_INITokenType_Value && tokeniser->data[pos] == '#') while (result.count && DN_INI_CharIsWhitespace_(result.data[result.count - 1])) result.count--; @@ -279,7 +280,7 @@ DN_INIToken DN_INI_NextToken(DN_INITokeniser const *tokeniser) } } - result.column = (uint32_t)(result.data - result.line_start); + result.column = (size_t)(result.data - result.line_start); return result; } @@ -302,7 +303,7 @@ static DN_INIToken DN_INI_MakeParseOutOfMemoryErrorToken_(DN_INIToken token) return result; } -DN_INISection *DN_INI_FindSectionStr8(DN_INISection *section, DN_INIStr8 str8) +DN_INISection *DN_INI_ChildSectionFromStr8(DN_INISection *section, DN_INIStr8 str8) { DN_INIStr8 section_name = str8; DN_INISection *result = section; @@ -323,26 +324,26 @@ DN_INISection *DN_INI_FindSectionStr8(DN_INISection *section, DN_INIStr8 str8) return result; } -DN_INISection *DN_INI_FindSection(DN_INISection *section, char const *name, uint32_t name_size) +DN_INISection *DN_INI_ChildSectionFromCStr(DN_INISection *section, char const *name, size_t name_size) { - DN_INISection *result = DN_INI_FindSectionStr8(section, DN_INI_Str8FromPtr(name, name_size)); + DN_INISection *result = DN_INI_ChildSectionFromStr8(section, DN_INI_Str8FromPtr(name, name_size)); return result; } -DN_INIKeyValue *DN_INI_KeyFromSectionStr8(DN_INISection *section, DN_INIStr8 str8) +DN_INIField *DN_INI_FieldFromSectionStr8(DN_INISection *section, DN_INIStr8 str8) { - DN_INIKeyValue *result = 0; + DN_INIField *result = 0; if (section) { DN_INIStr8BSplit split = DN_INI_Str8BSplitReverse(str8, DN_INIStr8Lit(".")); DN_INIStr8 find_key = str8; DN_INISection *find_section = section; if (split.rhs.size) { - find_section = DN_INI_FindSection(section, split.lhs.data, split.lhs.size); + find_section = DN_INI_ChildSectionFromCStr(section, split.lhs.data, split.lhs.size); find_key = split.rhs; } if (find_section) { - for (DN_INIKeyValue *it = find_section->first_key_value; !result && it; it = it->next) + for (DN_INIField *it = find_section->first_field; !result && it; it = it->next) if (DN_INI_Str8Eq(it->key, find_key)) result = it; } @@ -350,22 +351,99 @@ DN_INIKeyValue *DN_INI_KeyFromSectionStr8(DN_INISection *section, DN_INIStr8 str return result; } -DN_INIKeyValue *DN_INI_KeyFromSection(DN_INISection *section, char const *key, uint32_t key_size) +DN_INIField *DN_INI_FieldFromSection(DN_INISection *section, char const *key, size_t key_size) { - DN_INIKeyValue *result = DN_INI_KeyFromSectionStr8(section, DN_INI_Str8FromPtr(key, key_size)); + DN_INIField *result = DN_INI_FieldFromSectionStr8(section, DN_INI_Str8FromPtr(key, key_size)); return result; } -DN_INIParse DN_INI_ParseFromPtr(char const *buf, uint32_t count, char *base, uint32_t base_count) +DN_INIFieldUSize DN_INI_FieldUSizeFromSectionStr8(DN_INISection *section, DN_INIStr8 str8) +{ + DN_INIFieldUSize result = {}; + result.field = DN_INI_FieldFromSectionStr8(section, str8); + if (result.field) { + if (result.field->value_type == DN_INIFieldType_USize) { + result.value = result.field->value_usize; + result.success = true; + } else { + // NOTE: Try parse string as USize + // NOTE: Sanitize input/output + DN_INIStr8 value = result.field->value; + while (value.size && DN_INI_CharIsWhitespace_(value.data[0])) { + value.data++; + value.size--; + } + + // NOTE: Handle prefix '+' + if (value.size && value.data[0] == '+') { + value.data++; + value.size--; + } + + // NOTE: Convert the string number to the binary number + size_t value_usize = 0; + for (size_t index = 0; index < value.size; index++) { + char ch = value.data[index]; + uint64_t digit = ch - '0'; + if (!(ch >= '0' && ch <= '9')) + return result; + if (value_usize > (SIZE_MAX / 10) - digit) + return result; // NOTE: Overflow + value_usize = value_usize * 10 + digit; + } + result.value = value_usize; + result.success = true; + } + } + return result; +} + +DN_INIFieldStr8 DN_INI_FieldStr8FromSectionStr8(DN_INISection *section, DN_INIStr8 str8) +{ + DN_INIFieldStr8 result = {}; + result.field = DN_INI_FieldFromSectionStr8(section, str8); + if (result.field) { + result.value = result.field->value; + result.success = true; + } + return result; +} + +DN_INIFieldBool DN_INI_FieldBoolFromSectionStr8(DN_INISection *section, DN_INIStr8 str8) +{ + DN_INIFieldBool result = {}; + result.field = DN_INI_FieldFromSectionStr8(section, str8); + if (result.field) { + if (result.field->value_type == DN_INIFieldType_Bool) { + result.value = result.field->value_bool; + result.success = true; + } else { + if (DN_INI_Str8Eq(result.field->value, DN_INIStr8Lit("y")) || + DN_INI_Str8Eq(result.field->value, DN_INIStr8Lit("1")) || + DN_INI_Str8Eq(result.field->value, DN_INIStr8Lit("true"))) { + result.value = true; + result.success = true; + } else if (DN_INI_Str8Eq(result.field->value, DN_INIStr8Lit("m")) || + DN_INI_Str8Eq(result.field->value, DN_INIStr8Lit("0")) || + DN_INI_Str8Eq(result.field->value, DN_INIStr8Lit("false"))) { + result.value = false; + result.success = true; + } + } + } + return result; +} + +DN_INICore DN_INI_ParseFromPtr(char const *buf, size_t count, char *base, size_t base_count) { DN_INITokeniser tokeniser = DN_INI_TokeniserFromPtr(buf, count); DN_INIArena arena = {}; arena.base = base; arena.max = base_count; - DN_INIParse result = {}; + DN_INICore result = {}; DN_INISection *curr_section = &result.first_section; - DN_INIKeyValue *key_value = 0; + DN_INIField *field = 0; for (;;) { DN_INIToken token = DN_INI_NextToken(&tokeniser); if (token.type == DN_INITokenType_EndOfStream) @@ -373,16 +451,15 @@ DN_INIParse DN_INI_ParseFromPtr(char const *buf, uint32_t count, char *base, uin if (token.type == DN_INITokenType_Error) { result.error_token = token; - // fprintf(stderr, "ERROR: INI parsing failed at %zu:%zu: %.*s. String was '%.*s'\n", token.line, token.column, (int)token.error.size, token.error.data, (int)token.count, token.data); break; } switch (token.type) { - case DN_INITokenType_EndOfStream: /*FALLTHRU*/ - case DN_INITokenType_Error: /*FALLTHRU*/ - case DN_INITokenType_Nil: DN_INI_Assert(!"Invalid code path"); break; - case DN_INITokenType_KeyValueSeparator: break; - case DN_INITokenType_Comment: break; + case DN_INITokenType_EndOfStream: /*FALLTHRU*/ + case DN_INITokenType_Error: /*FALLTHRU*/ + case DN_INITokenType_Nil: DN_INI_Assert(!"Invalid code path"); break; + case DN_INITokenType_FieldSeparator: break; + case DN_INITokenType_Comment: break; case DN_INITokenType_Section: { DN_INISection *parent = &result.first_section; @@ -393,7 +470,7 @@ DN_INIParse DN_INI_ParseFromPtr(char const *buf, uint32_t count, char *base, uin if (split.lhs.size == 0) break; - DN_INISection *next_section = DN_INI_FindSection(parent, split.lhs.data, split.lhs.size); + DN_INISection *next_section = DN_INI_ChildSectionFromCStr(parent, split.lhs.data, split.lhs.size); if (!next_section) { result.total_sections_count++; next_section = (DN_INISection *)DN_INI_ArenaAlloc(&arena, sizeof(*parent)); @@ -421,33 +498,33 @@ DN_INIParse DN_INI_ParseFromPtr(char const *buf, uint32_t count, char *base, uin } break; case DN_INITokenType_Key: { - key_value = DN_INI_KeyFromSection(curr_section, token.data, token.count); - if (!key_value) { - result.total_key_values_count++; - key_value = (DN_INIKeyValue *)DN_INI_ArenaAlloc(&arena, sizeof(*key_value)); - if (base && !key_value) { + field = DN_INI_FieldFromSection(curr_section, token.data, token.count); + if (!field) { + result.total_fields_count++; + field = (DN_INIField *)DN_INI_ArenaAlloc(&arena, sizeof(*field)); + if (base && !field) { result.error_token = DN_INI_MakeParseOutOfMemoryErrorToken_(token); return result; } - if (key_value) { - key_value->key.data = token.data; - key_value->key.size = token.count; + if (field) { + field->key.data = token.data; + field->key.size = token.count; } if (curr_section) { - if (!curr_section->first_key_value) - curr_section->first_key_value = key_value; - if (curr_section->last_key_value) - curr_section->last_key_value->next = key_value; - curr_section->last_key_value = key_value; - curr_section->key_values_count++; + if (!curr_section->first_field) + curr_section->first_field = field; + if (curr_section->last_field) + curr_section->last_field->next = field; + curr_section->last_field = field; + curr_section->fields_count++; } } } break; case DN_INITokenType_MultilineValue: { - uint32_t bytes_req = token.count; + size_t bytes_req = token.count; if (tokeniser.prev_token.type == DN_INITokenType_Value) { // NOTE: We saw a value, then the next token was a multiline value, we will merge these // values into 1 stream, so we need to copy the previous string out as well. @@ -455,9 +532,9 @@ DN_INIParse DN_INI_ParseFromPtr(char const *buf, uint32_t count, char *base, uin } result.memory_required += bytes_req; - if (curr_section && key_value) { - DN_INI_Assert(curr_section->key_values_count); - DN_INI_Assert(key_value->key.size); + if (curr_section && field) { + DN_INI_Assert(curr_section->fields_count); + DN_INI_Assert(field->key.size); char *string = (char *)DN_INI_ArenaAlloc(&arena, bytes_req); if (!string) { @@ -465,41 +542,308 @@ DN_INIParse DN_INI_ParseFromPtr(char const *buf, uint32_t count, char *base, uin return result; } - - char *dest = string; if (tokeniser.prev_token.type == DN_INITokenType_Value) { - DN_INI_Memcpy(dest, tokeniser.prev_token.data, tokeniser.prev_token.count); - dest += tokeniser.prev_token.count; - key_value->value.data = string; - key_value->value.size = tokeniser.prev_token.count; + + field->value.data = string; + field->value.size = 0; + + for (size_t index = 0; index < tokeniser.prev_token.count; index++) { + char ch = tokeniser.prev_token.data[index]; + char next = index + 1 < tokeniser.prev_token.count ? tokeniser.prev_token.data[index + 1] : 0; + if (ch == '\\' && next == 'n') { + field->value.data[field->value.size++] = '\n'; + index++; + } else { + field->value.data[field->value.size++] = ch; + } + } } else { // NOTE: If we have a multi-line value we are accumulating onto the same key-value. // Invariant to this is that the arena is only being used to allocate contiguous memory // for the string. Essentially each time we visit this branch we're just bumping the // capacity of the original string we allocated at the start of the multi-line value. - // This is what this assert checks, that we're expanding in place the string and there - // hasn't been some other allocation that took place inbetween that broke continuity. - DN_INI_Assert(key_value->value.data + key_value->value.size == string); } - DN_INI_Memcpy(dest, token.data, token.count); - key_value->value.size += token.count; + for (size_t index = 0; index < token.count; index++) { + char ch = token.data[index]; + char next = index + 1 < token.count ? token.data[index + 1] : 0; + if (ch == '\\' && next == 'n') { + field->value.data[field->value.size++] = '\n'; + index++; + } else { + field->value.data[field->value.size++] = ch; + } + } } } break; case DN_INITokenType_Value: { - if (curr_section && key_value) { - DN_INI_Assert(curr_section->key_values_count); - DN_INI_Assert(key_value->key.size); - key_value->value.data = token.data; - key_value->value.size = token.count; + // NOTE: Scan the string to see if it has a line break, if so we allocate memory for it and + // and convert the line break into a single-byte newline + size_t bytes_req = 0; + for (size_t index = 0; index < token.count; index++) { + char ch = token.data[index]; + char next = index + 1 < token.count ? token.data[index + 1] : 0; + if (ch == '\\' && next == 'n') { + bytes_req = token.count; + break; + } + } + + result.memory_required += bytes_req; + if (curr_section && field) { + DN_INI_Assert(curr_section->fields_count); + DN_INI_Assert(field->key.size); + if (bytes_req) { + field->value.data = (char *)DN_INI_ArenaAlloc(&arena, bytes_req); + if (!field->value.data) { + result.error_token = DN_INI_MakeParseOutOfMemoryErrorToken_(token); + return result; + } + + for (size_t index = 0; index < token.count; index++) { + char ch = token.data[index]; + char next = index + 1 < token.count ? token.data[index + 1] : 0; + if (ch == '\\' && next == 'n') { + field->value.data[field->value.size++] = '\n'; + index++; + } else { + field->value.data[field->value.size++] = ch; + } + } + DN_INI_Assert(field->value.size <= bytes_req); + } else { + field->value.data = token.data; + field->value.size = token.count; + } } } break; } DN_INI_EatToken(&tokeniser, token); } - result.memory_required += (result.total_sections_count * sizeof(DN_INISection)) + (result.total_key_values_count * sizeof(DN_INIKeyValue)); + result.memory_required += (result.total_sections_count * sizeof(DN_INISection)) + (result.total_fields_count * sizeof(DN_INIField)); + return result; +} + +void DN_INI_AppendValue(DN_INISection *section, DN_INIField *field) +{ + if (!section->first_field) + section->first_field = field; + if (section->last_field) + section->last_field->next = field; + section->last_field = field; +} + +DN_INISection *DN_INI_AppendSectionF(DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, char const *fmt, ...) +{ + va_list args, args_copy; + va_start(args, fmt); + va_copy(args_copy, args); + int size_req = vsnprintf(0, 0, fmt, args); + va_end(args); + + DN_INISection *result = 0; + size_t mem_req = sizeof(*result) + (size_req + 1); + ini->memory_required += mem_req; + if (arena && arena->used + mem_req <= arena->max) { + result = (DN_INISection *)DN_INI_ArenaAlloc(arena, sizeof(*result)); + result->name.data = (char *)DN_INI_ArenaAlloc(arena, size_req + 1); + result->name.size = size_req; + vsnprintf(result->name.data, result->name.size + 1, fmt, args_copy); + + if (result) { + if (section) { + if (!section->child_first) + section->child_first = result; + if (section->child_last) + section->child_last->next = result; + section->child_last = result; + } + if (result) { + if (result->parent) + result->parent->child_count++; + result->parent = section; + } + } + } + va_end(args_copy); + + return result; +} + +static DN_INIField *DN_INI_AllocFieldInternal(DN_INIStr8 key, DN_INIArena *arena) +{ + DN_INIField *result = 0; + size_t mem_req = sizeof(*result) + (key.size + 1); + if (arena->used + mem_req <= arena->max) { + result = (DN_INIField *)DN_INI_ArenaAlloc(arena, sizeof(*result)); + result->key.data = (char *)DN_INI_ArenaAlloc(arena, key.size + 1); + result->key.size = key.size; + DN_INI_Memcpy(result->key.data, key.data, key.size); + result->key.data[result->key.size] = 0; + } + return result; +} + +DN_INIField *DN_INI_AppendKeyBool(DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, bool value) +{ + DN_INIField *result = 0; + size_t mem_req = sizeof(*result) + key.size + sizeof(value); + ini->memory_required += mem_req; + if (arena && arena->used + mem_req <= arena->max) { + result = DN_INI_AllocFieldInternal(key, arena); + result->value_bool = value; + result->value_type = DN_INIFieldType_Bool; + DN_INI_Memcpy(result->key.data, key.data, key.size); + DN_INI_AppendValue(section, result); + } + return result; +} + +DN_INIField *DN_INI_AppendKeyPtrBool(DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, char const *key, size_t key_size, bool value) +{ + DN_INIStr8 key_str8 = DN_INI_Str8FromPtr(key, key_size); + DN_INIField *result = DN_INI_AppendKeyBool(ini, arena, section, key_str8, value); + return result; +} + +DN_INIField *DN_INI_AppendKeyUSize(DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, size_t value) +{ + DN_INIField *result = 0; + size_t mem_req = sizeof(*result) + key.size + sizeof(value); + ini->memory_required += mem_req; + if (arena && arena->used + mem_req <= arena->max) { + result = DN_INI_AllocFieldInternal(key, arena); + result->value_usize = value; + result->value_type = DN_INIFieldType_USize; + DN_INI_Memcpy(result->key.data, key.data, key.size); + DN_INI_AppendValue(section, result); + } + return result; +} + +DN_INIField *DN_INI_AppendKeyPtrUSize(DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, char const *key, size_t key_size, size_t value) +{ + DN_INIStr8 key_str8 = DN_INI_Str8FromPtr(key, key_size); + DN_INIField *result = DN_INI_AppendKeyUSize(ini, arena, section, key_str8, value); + return result; +} + +DN_INIField *DN_INI_AppendKeyCStr8(DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, char const *value, size_t value_size) +{ + DN_INIField *result = 0; + size_t mem_req = sizeof(*result) + (key.size + 1) + value_size; + ini->memory_required += mem_req; + if (arena && arena->used + mem_req <= arena->max) { + result = DN_INI_AllocFieldInternal(key, arena); + result->value.data = (char *)DN_INI_ArenaAlloc(arena, value_size); + result->value.size = value_size; + result->value_type = DN_INIFieldType_String; + DN_INI_Memcpy(result->value.data, value, value_size); + DN_INI_AppendValue(section, result); + } + return result; +} + +DN_INIField *DN_INI_AppendKeyF(DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, char const *fmt, ...) +{ + va_list args, args_copy; + va_start(args, fmt); + va_copy(args_copy, args); + int size_req = vsnprintf(0, 0, fmt, args); + va_end(args); + + DN_INIField *result = 0; + size_t mem_req = sizeof(*result) + (key.size + 1) + (size_req + 1); + ini->memory_required += mem_req; + if (arena && arena->used + mem_req <= arena->max) { + result = DN_INI_AllocFieldInternal(key, arena); + result->value.data = (char *)DN_INI_ArenaAlloc(arena, size_req + 1); + result->value.size = size_req; + vsnprintf(result->value.data, result->value.size + 1, fmt, args_copy); + result->value.data[result->value.size] = 0; + DN_INI_AppendValue(section, result); + } + va_end(args_copy); + + return result; +} + +static void DN_INI_Str8BuilderAppend(DN_INIStr8Builder *builder, char const *fmt, ...) +{ + va_list args; + va_list args_copy; + va_start(args, fmt); + va_copy(args_copy, args); + int size_req = vsnprintf(0, 0, fmt, args); + va_end(args); + + builder->size_req += size_req; + if (builder->used + size_req <= builder->max) { + vsnprintf(builder->data + builder->used, builder->max - builder->used, fmt, args_copy); + builder->used += size_req; + } + va_end(args_copy); +} + +DN_INIStr8FromResult DN_INI_Str8FromINI(DN_INICore const *ini, char *buffer, size_t size) +{ + DN_INIStr8FromResult result = {}; + DN_INISection const *section_stack[64] = {}; + size_t section_stack_count = 0; + if (ini->first_section.child_first) + section_stack[section_stack_count++] = &ini->first_section; + + DN_INIStr8Builder builder = {}; + builder.data = buffer; + builder.max = size; + + DN_INISection *parent_stack[32] = {}; + size_t parent_stack_count = 0; + for (; section_stack_count;) { + DN_INISection const *it = section_stack[--section_stack_count]; + + if (it != &ini->first_section) { + DN_INI_Str8BuilderAppend(&builder, "["); + for (DN_INISection *parent = it->parent; parent; parent = parent->parent) + if (parent->name.size) + parent_stack[parent_stack_count++] = parent; + for (size_t index = parent_stack_count - 1; index < parent_stack_count; index--) { + DN_INISection *parent = parent_stack[index]; + DN_INI_Str8BuilderAppend(&builder, "%.*s.", (int)parent->name.size, parent->name.data); + } + parent_stack_count = 0; + DN_INI_Str8BuilderAppend(&builder, "%.*s]\n", (int)it->name.size, it->name.data); + } + + for (DN_INIField *field = it->first_field; field; field = field->next) { + DN_INI_Str8BuilderAppend(&builder, "%.*s = ", (int)field->key.size, field->key.data); + switch (field->value_type) { + case DN_INIFieldType_String: DN_INI_Str8BuilderAppend(&builder, "%.*s\n", (int)field->value.size, field->value.data); break; + case DN_INIFieldType_Bool: DN_INI_Str8BuilderAppend(&builder, "%d\n", field->value_bool); break; + case DN_INIFieldType_USize: DN_INI_Str8BuilderAppend(&builder, "%zu\n", field->value_usize); break; + } + } + + if (it->next) + section_stack[section_stack_count++] = it->next; + if (it->child_first) + section_stack[section_stack_count++] = it->child_first; + + if (section_stack_count) + DN_INI_Str8BuilderAppend(&builder, "\n"); + } + + result.size_req = builder.size_req; + if (buffer) { + result.str8.data = builder.data; + result.str8.size = builder.used; + result.success = true; + } else { + result.success = true; + } + return result; } @@ -515,12 +859,12 @@ void DN_INI_UnitTests() " version = attr: this8.__version__\n" "\n"; - DN_INIParse parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); + DN_INICore parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); DN_INI_Assert(parse.total_sections_count == 1); - DN_INI_Assert(parse.total_key_values_count == 2); + DN_INI_Assert(parse.total_fields_count == 2); - char parse_memory[sizeof(DN_INIKeyValue) * 2 + sizeof(DN_INISection) * 1]; + char parse_memory[sizeof(DN_INIField) * 2 + sizeof(DN_INISection) * 1]; parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, parse_memory, sizeof(parse_memory)); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); } @@ -534,12 +878,12 @@ void DN_INI_UnitTests() " version = attr: this8.__version__\n" "\n"; - DN_INIParse parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); + DN_INICore parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); DN_INI_Assert(parse.total_sections_count == 1); - DN_INI_Assert(parse.total_key_values_count == 3); + DN_INI_Assert(parse.total_fields_count == 3); - char parse_memory[sizeof(DN_INIKeyValue) * 3 + sizeof(DN_INISection) * 1]; + char parse_memory[sizeof(DN_INIField) * 3 + sizeof(DN_INISection) * 1]; parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, parse_memory, sizeof(parse_memory)); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); } @@ -550,12 +894,12 @@ void DN_INI_UnitTests() "first=hello\n" "[metadata]\n\n"; - DN_INIParse parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); + DN_INICore parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); DN_INI_Assert(parse.total_sections_count == 1); - DN_INI_Assert(parse.total_key_values_count == 1); + DN_INI_Assert(parse.total_fields_count == 1); - char parse_memory[sizeof(DN_INIKeyValue) * 1 + sizeof(DN_INISection) * 2]; + char parse_memory[sizeof(DN_INIField) * 1 + sizeof(DN_INISection) * 2]; parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, parse_memory, sizeof(parse_memory)); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); } @@ -566,12 +910,12 @@ void DN_INI_UnitTests() "[metadata]\n\n" "[metadata2]\n\n"; - DN_INIParse parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); + DN_INICore parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); DN_INI_Assert(parse.total_sections_count == 2); - DN_INI_Assert(parse.total_key_values_count == 0); + DN_INI_Assert(parse.total_fields_count == 0); - char parse_memory[sizeof(DN_INIKeyValue) * 0 + sizeof(DN_INISection) * 2]; + char parse_memory[sizeof(DN_INIField) * 0 + sizeof(DN_INISection) * 2]; parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, parse_memory, sizeof(parse_memory)); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); } @@ -584,24 +928,24 @@ void DN_INI_UnitTests() "[metadata]\n" "foo=baz\n"; - DN_INIParse parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); + DN_INICore parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); // NOTE: Because sections can override each other, when parsing with no memory, e.g. no context // we can't easily tell if a section is repeated or not without retokenising the entire file // every time we hit a section. Then the total section count returned in the initial pass is // an estimate. The same goes with the key-values DN_INI_Assert(parse.total_sections_count == 2); - DN_INI_Assert(parse.total_key_values_count == 2); + DN_INI_Assert(parse.total_fields_count == 2); - char parse_memory[sizeof(DN_INIKeyValue) * 1 + sizeof(DN_INISection) * 1]; + char parse_memory[sizeof(DN_INIField) * 1 + sizeof(DN_INISection) * 1]; parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, parse_memory, sizeof(parse_memory)); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); DN_INI_Assert(parse.total_sections_count == 1); - DN_INI_Assert(parse.total_key_values_count == 1); + DN_INI_Assert(parse.total_fields_count == 1); DN_INI_Assert(parse.first_section.child_first); - DN_INI_Assert(parse.first_section.child_first->first_key_value); - DN_INI_Assert(parse.first_section.child_first->first_key_value == parse.first_section.child_first->last_key_value); - DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_key_value->value, DN_INIStr8Lit("baz"))); + DN_INI_Assert(parse.first_section.child_first->first_field); + DN_INI_Assert(parse.first_section.child_first->first_field == parse.first_section.child_first->last_field); + DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_field->value, DN_INIStr8Lit("baz"))); } // NOTE: Out-of-order repeated section override @@ -613,20 +957,20 @@ void DN_INI_UnitTests() "[metadata]\n" "foo=baz\n"; - DN_INIParse parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); + DN_INICore parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); DN_INI_Assert(parse.total_sections_count == 3); - DN_INI_Assert(parse.total_key_values_count == 2); + DN_INI_Assert(parse.total_fields_count == 2); - char parse_memory[sizeof(DN_INIKeyValue) * 1 + sizeof(DN_INISection) * 2]; + char parse_memory[sizeof(DN_INIField) * 1 + sizeof(DN_INISection) * 2]; parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, parse_memory, sizeof(parse_memory)); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); DN_INI_Assert(parse.total_sections_count == 2); - DN_INI_Assert(parse.total_key_values_count == 1); + DN_INI_Assert(parse.total_fields_count == 1); DN_INI_Assert(parse.first_section.child_first); - DN_INI_Assert(parse.first_section.child_first->first_key_value); - DN_INI_Assert(parse.first_section.child_first->first_key_value == parse.first_section.child_first->last_key_value); - DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_key_value->value, DN_INIStr8Lit("baz"))); + DN_INI_Assert(parse.first_section.child_first->first_field); + DN_INI_Assert(parse.first_section.child_first->first_field == parse.first_section.child_first->last_field); + DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_field->value, DN_INIStr8Lit("baz"))); } // NOTE: Subsection @@ -637,21 +981,21 @@ void DN_INI_UnitTests() "[metadata.test]\n" "hello=world\n"; - DN_INIParse parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); + DN_INICore parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); DN_INI_Assert(parse.total_sections_count == 3); - DN_INI_Assert(parse.total_key_values_count == 2); + DN_INI_Assert(parse.total_fields_count == 2); - char parse_memory[sizeof(DN_INIKeyValue) * 2 + sizeof(DN_INISection) * 3]; + char parse_memory[sizeof(DN_INIField) * 2 + sizeof(DN_INISection) * 3]; parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, parse_memory, sizeof(parse_memory)); DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->name, DN_INIStr8Lit("metadata"))); - DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_key_value->key, DN_INIStr8Lit("foo"))); - DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_key_value->value, DN_INIStr8Lit("bar"))); + DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_field->key, DN_INIStr8Lit("foo"))); + DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_field->value, DN_INIStr8Lit("bar"))); DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->child_first->name, DN_INIStr8Lit("test"))); - DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->child_first->first_key_value->key, DN_INIStr8Lit("hello"))); - DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->child_first->first_key_value->value, DN_INIStr8Lit("world"))); + DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->child_first->first_field->key, DN_INIStr8Lit("hello"))); + DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->child_first->first_field->value, DN_INIStr8Lit("world"))); } // NOTE: Repeated subsections @@ -667,26 +1011,26 @@ void DN_INI_UnitTests() "[metadata.test]\n" "foo=baz\n"; - DN_INIParse parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); + DN_INICore parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); DN_INI_Assert(parse.total_sections_count == 6); - DN_INI_Assert(parse.total_key_values_count == 4); + DN_INI_Assert(parse.total_fields_count == 4); - char parse_memory[sizeof(DN_INIKeyValue) * 2 + sizeof(DN_INISection) * 2]; + char parse_memory[sizeof(DN_INIField) * 2 + sizeof(DN_INISection) * 2]; parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, parse_memory, sizeof(parse_memory)); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->name, DN_INIStr8Lit("metadata"))); - DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_key_value->key, DN_INIStr8Lit("foo"))); - DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_key_value->value, DN_INIStr8Lit("baz"))); + DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_field->key, DN_INIStr8Lit("foo"))); + DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_field->value, DN_INIStr8Lit("baz"))); DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->child_first->name, DN_INIStr8Lit("test"))); - DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->child_first->first_key_value->key, DN_INIStr8Lit("foo"))); - DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->child_first->first_key_value->value, DN_INIStr8Lit("baz"))); + DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->child_first->first_field->key, DN_INIStr8Lit("foo"))); + DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->child_first->first_field->value, DN_INIStr8Lit("baz"))); - DN_INIKeyValue *key_value = DN_INI_KeyFromSectionStr8(&parse.first_section, DN_INIStr8Lit("metadata.test.foo")); - DN_INI_Assert(DN_INI_Str8Eq(key_value->key, DN_INIStr8Lit("foo"))); - DN_INI_Assert(DN_INI_Str8Eq(key_value->value, DN_INIStr8Lit("baz"))); + DN_INIField *field = DN_INI_FieldFromSectionStr8(&parse.first_section, DN_INIStr8Lit("metadata.test.foo")); + DN_INI_Assert(DN_INI_Str8Eq(field->key, DN_INIStr8Lit("foo"))); + DN_INI_Assert(DN_INI_Str8Eq(field->value, DN_INIStr8Lit("baz"))); } // NOTE: Multi line value @@ -700,21 +1044,21 @@ void DN_INI_UnitTests() "j" ; - DN_INIParse parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); + DN_INICore parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); DN_INI_Assert(parse.total_sections_count == 1); - DN_INI_Assert(parse.total_key_values_count == 2); + DN_INI_Assert(parse.total_fields_count == 2); - char parse_memory[256]; + char parse_memory[300]; DN_INI_Assert(parse.memory_required <= sizeof(parse_memory)); parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, parse_memory, sizeof(parse_memory)); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); - DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_key_value->key, DN_INIStr8Lit("foo"))); - DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_key_value->value, DN_INIStr8Lit("bar baz"))); + DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_field->key, DN_INIStr8Lit("foo"))); + DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_field->value, DN_INIStr8Lit("bar baz"))); - DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->last_key_value->key, DN_INIStr8Lit("abc"))); - DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->last_key_value->value, DN_INIStr8Lit("def ghij"))); + DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->last_field->key, DN_INIStr8Lit("abc"))); + DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->last_field->value, DN_INIStr8Lit("def ghij"))); } // NOTE: Multi line immediately after key-value separator @@ -726,18 +1070,39 @@ void DN_INI_UnitTests() "j" ; - DN_INIParse parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); + DN_INICore parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); DN_INI_Assert(parse.total_sections_count == 1); - DN_INI_Assert(parse.total_key_values_count == 1); + DN_INI_Assert(parse.total_fields_count == 1); char parse_memory[256]; DN_INI_Assert(parse.memory_required <= sizeof(parse_memory)); parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, parse_memory, sizeof(parse_memory)); DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); - DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_key_value->key, DN_INIStr8Lit("foo"))); - DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_key_value->value, DN_INIStr8Lit("bazj"))); + DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_field->key, DN_INIStr8Lit("foo"))); + DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_field->value, DN_INIStr8Lit("bazj"))); + } + + // NOTE: Empty section + { + char const EXAMPLE[] = + "[metadata]\n" + "foo=\n" + "[empty]\n" + ; + + DN_INICore parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, 0, 0); + DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); + DN_INI_Assert(parse.total_sections_count == 2); + DN_INI_Assert(parse.total_fields_count == 1); + + char parse_memory[400]; + DN_INI_Assert(parse.memory_required <= sizeof(parse_memory)); + + parse = DN_INI_ParseFromPtr(EXAMPLE, sizeof(EXAMPLE) - 1, parse_memory, sizeof(parse_memory)); + DN_INI_Assert(parse.error_token.type == DN_INITokenType_Nil); + DN_INI_Assert(DN_INI_Str8Eq(parse.first_section.child_first->first_field->key, DN_INIStr8Lit("foo"))); } } #endif diff --git a/Source/Standalone/dn_ini.h b/Source/Standalone/dn_ini.h index 0453966..18b7507 100644 --- a/Source/Standalone/dn_ini.h +++ b/Source/Standalone/dn_ini.h @@ -1,13 +1,20 @@ #if !defined(DN_INI_H) #define DN_INI_H -#include // uint32_t +#include // size_t #if !defined(DN_INI_Assert) #include #define DN_INI_Assert(expr) assert(expr) #endif +#include + +#if !defined(DN_INI_VSNPrintF) + #include + #define DN_INI_VSNPrintF(buffer, size, fmt, args) vsnprintf(buffer, size, fmt, args) +#endif + #if !defined(DN_INI_Memset) || !defined(DN_INI_Memcmp) || !defined(DN_INI_Memcpy) #include #if !defined(DN_INI_Memset) @@ -27,7 +34,7 @@ typedef enum DN_INITokenType { DN_INITokenType_Nil, DN_INITokenType_Section, DN_INITokenType_Key, - DN_INITokenType_KeyValueSeparator, + DN_INITokenType_FieldSeparator, DN_INITokenType_MultilineValue, DN_INITokenType_Value, DN_INITokenType_Comment, @@ -37,7 +44,7 @@ typedef enum DN_INITokenType { typedef struct DN_INIStr8 { char *data; - uint32_t size; + size_t size; } DN_INIStr8; #if defined(__cplusplus) @@ -49,63 +56,133 @@ typedef struct DN_INIStr8 { typedef struct DN_INIToken { char *data; DN_INITokenType type; - uint32_t count; - uint32_t next_p; - bool new_line; + size_t count; + size_t next_p; + bool line_start_new_line; // NOTE: Line metadata DN_INIStr8 error; - uint32_t line; - uint32_t column; - char *line_start; + size_t line; + size_t column; + char * line_start; } DN_INIToken; typedef struct DN_INITokeniser { - char *data; - char *line_start; - uint32_t count; - uint32_t pos; - DN_INIToken prev_token; - uint32_t line; - uint32_t column; + char *data; + char *line_start; + size_t count; + size_t pos; + DN_INIToken prev_token; + size_t line; + size_t column; } DN_INITokeniser; -typedef struct DN_INIKeyValue DN_INIKeyValue; -struct DN_INIKeyValue { +typedef enum DN_INIFieldType { + DN_INIFieldType_String, + DN_INIFieldType_Bool, + DN_INIFieldType_USize, +} DN_INIFieldType; + +typedef struct DN_INIField DN_INIField; +struct DN_INIField { DN_INIStr8 key; + DN_INIFieldType value_type; DN_INIStr8 value; - DN_INIKeyValue *next; + bool value_bool; + size_t value_usize; + DN_INIField *next; }; typedef struct DN_INISection DN_INISection; struct DN_INISection { - DN_INIStr8 name; - DN_INIKeyValue *first_key_value; - DN_INIKeyValue *last_key_value; - uint32_t key_values_count; - DN_INIToken token; - DN_INISection *next, *parent; - DN_INISection *child_first, *child_last; + DN_INIStr8 name; + DN_INIField *first_field; + DN_INIField *last_field; + size_t fields_count; + DN_INIToken token; + DN_INISection *next, *parent; + DN_INISection *child_first, *child_last; + size_t child_count; }; -typedef struct DN_INIParse { +typedef struct DN_INICore DN_INICore; +struct DN_INICore { DN_INISection first_section; - uint32_t total_sections_count; - uint32_t total_key_values_count; + size_t total_sections_count; + size_t total_fields_count; DN_INIToken error_token; - uint32_t memory_required; -} DN_INIParse; + size_t memory_required; +}; -DN_INITokeniser DN_INI_TokeniserFromPtr (char const *buf, uint32_t count); -DN_INIToken DN_INI_NextToken (DN_INITokeniser const *tokeniser); -void DN_INI_EatToken (DN_INITokeniser *tokeniser, DN_INIToken token); -DN_INISection * DN_INI_FindSectionStr8 (DN_INISection *section, DN_INIStr8 str8); -DN_INISection * DN_INI_FindSection (DN_INISection *section, char const *name, uint32_t name_size); -DN_INIKeyValue *DN_INI_KeyFromSectionStr8(DN_INISection *section, DN_INIStr8 str8); -DN_INIKeyValue *DN_INI_KeyFromSection (DN_INISection *section, char const *key, uint32_t key_size); -DN_INIParse DN_INI_ParseFromPtr (char const *buf, uint32_t count, char *base, uint32_t base_count); +typedef struct DN_INIArena DN_INIArena; +struct DN_INIArena { + char *base; + size_t used, max; +}; + +typedef struct DN_INIStr8FromResult DN_INIStr8FromResult; +struct DN_INIStr8FromResult { + bool success; + DN_INIStr8 str8; + size_t size_req; +}; + +typedef struct DN_INIFieldUSize DN_INIFieldUSize; +struct DN_INIFieldUSize +{ + bool success; + DN_INIField *field; + size_t value; +}; + +typedef struct DN_INIFieldStr8 DN_INIFieldStr8; +struct DN_INIFieldStr8 +{ + bool success; + DN_INIField *field; + DN_INIStr8 value; +}; + +typedef struct DN_INIFieldBool DN_INIFieldBool; +struct DN_INIFieldBool +{ + bool success; + DN_INIField *field; + bool value; +}; + + +// NOTE: Utilities +int DN_INI_SNPrintF_ (char const *buffer, size_t size, char const *fmt, ...); +void * DN_INI_ArenaAlloc (DN_INIArena *arena, size_t size); +DN_INIStr8 DN_INI_Str8FromPtr (char const *data, size_t count); + +// NOTE: Tokeniser/Parsing +DN_INITokeniser DN_INI_TokeniserFromPtr (char const *buf, size_t count); +DN_INIToken DN_INI_NextToken (DN_INITokeniser const *tokeniser); +void DN_INI_EatToken (DN_INITokeniser *tokeniser, DN_INIToken token); + +// NOTE: Lookup +DN_INISection * DN_INI_ChildSectionFromStr8 (DN_INISection *section, DN_INIStr8 str8); +DN_INISection * DN_INI_ChildSectionFromCStr (DN_INISection *section, char const *name, size_t name_size); +DN_INIField * DN_INI_FieldFromSectionStr8 (DN_INISection *section, DN_INIStr8 str8); +DN_INIField * DN_INI_FieldFromSection (DN_INISection *section, char const *key, size_t key_size); +DN_INIFieldUSize DN_INI_FieldUSizeFromSectionStr8(DN_INISection *section, DN_INIStr8 str8); +DN_INIFieldStr8 DN_INI_FieldStr8FromSectionStr8 (DN_INISection *section, DN_INIStr8 str8); +DN_INIFieldBool DN_INI_FieldBoolFromSectionStr8 (DN_INISection *section, DN_INIStr8 str8); +DN_INICore DN_INI_ParseFromPtr (char const *buf, size_t count, char *base, size_t base_count); + +// NOTE: Building +DN_INISection * DN_INI_AppendSectionF (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, char const *fmt, ...); +DN_INIField * DN_INI_AppendKeyBool (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, bool value); +DN_INIField * DN_INI_AppendKeyPtrBool (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, char const *key, size_t key_size, bool value); +DN_INIField * DN_INI_AppendKeyUSize (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, size_t value); +DN_INIField * DN_INI_AppendKeyPtrUSize (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, char const *key, size_t key_size, size_t value); +DN_INIField * DN_INI_AppendKeyCStr8 (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, char const *value, size_t value_size); +DN_INIField * DN_INI_AppendKeyF (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, char const *fmt, ...); +void DN_INI_AppendField (DN_INISection *section, DN_INIField *field); #if defined(DN_INI_WITH_UNIT_TESTS) -void DN_INI_UnitTests (); +void DN_INI_UnitTests (); #endif #endif // !defined(DN_INI_H) diff --git a/Source/dn_base_inc.cpp b/Source/dn_base_inc.cpp index 99ed25c..fad8081 100644 --- a/Source/dn_base_inc.cpp +++ b/Source/dn_base_inc.cpp @@ -2,7 +2,4 @@ #include "Base/dn_base.cpp" #include "Base/dn_base_containers.cpp" -#include "Base/dn_base_convert.cpp" -#include "Base/dn_base_mem.cpp" -#include "Base/dn_base_string.cpp" #include "Base/dn_base_log.cpp" diff --git a/Source/dn_base_inc.h b/Source/dn_base_inc.h index 1fd9b29..d345e6b 100644 --- a/Source/dn_base_inc.h +++ b/Source/dn_base_inc.h @@ -56,10 +56,7 @@ #include "Base/dn_base.h" #include "Base/dn_base_os.h" #include "Base/dn_base_assert.h" -#include "Base/dn_base_mem.h" #include "Base/dn_base_log.h" -#include "Base/dn_base_string.h" #include "Base/dn_base_containers.h" -#include "Base/dn_base_convert.h" #endif // !defined(DN_BASE_INC_H)