Compare commits

...

2 Commits

Author SHA1 Message Date
d6ce046775 dqn: Fix cstring errors 2023-05-12 18:32:41 +09:00
d0e7bf9b1a dqn: Add printing styles 2023-05-12 18:09:02 +09:00
2 changed files with 303 additions and 109 deletions

365
dqn.h
View File

@ -4,7 +4,7 @@
// =================================================================================================
// Table Of Contents | Compile out with #define | Description
// =================================================================================================
// [$CFGM] Config macros | | Compile time customisation of library
// [$CFgM] Config macros | | Compile time customisation of library
// [$CMAC] Compiler macros | | Macros for the compiler
// [$INCL] Include files | | Standard library Include dependencies
// [$MACR] Macros | | Define macros used in the library
@ -48,7 +48,7 @@
// =================================================================================================
//
// =================================================================================================
// [$CFGM] Config macros | | Compile time customisation of library
// [$CFgM] Config macros | | Compile time customisation of library
// =================================================================================================
// #define DQN_IMPLEMENTATION
// Define this in one and only one C++ file to enable the implementation
@ -406,7 +406,12 @@ typedef enum Dqn_ZeroMem {
#define Dqn_CompilerReadBarrierAndCPUReadFence _ReadBarrier(); _mm_lfence()
#define Dqn_CompilerWriteBarrierAndCPUWriteFence _WriteBarrier(); _mm_sfence()
#elif defined(DQN_COMPILER_GCC) || defined(DQN_COMPILER_CLANG)
#if defined(__ANDROID__)
#else
#include <x86intrin.h>
#endif
#define Dqn_Atomic_AddU32(target, value) __atomic_fetch_add(target, value, __ATOMIC_ACQ_REL)
#define Dqn_Atomic_AddU64(target, value) __atomic_fetch_add(target, value, __ATOMIC_ACQ_REL)
#define Dqn_Atomic_SubU32(target, value) __atomic_fetch_sub(target, value, __ATOMIC_ACQ_REL)
@ -855,16 +860,6 @@ void Dqn_Allocator_Dealloc_(DQN_LEAK_TRACE_FUNCTION Dqn_Allocator allocator, voi
// @return The left hand side of the split string. The original pointer is
// returned if the arguments were invalid.
//
// @proc Dqn_CString8_Eq, Dqn_CString8_EqInsensitive
// @desc Compare a string for equality with or without case sensitivity.
// @param[in] lhs The first string to compare equality with
// @param[in] rhs The second string to compare equality with
// @param[in] lhs The first string's size
// @param[in] rhs The second string's size
// @param[in] eq_case Set the comparison to be case sensitive or insensitive
// @return True if the arguments are valid, non-null and the strings
// are equal, false otherwise.
//
// @proc Dqn_CString8_StartsWith, Dqn_CString8_StartsWithInsensitive,
// Dqn_CString8_EndsWith, Dqn_CString8_EndswithInsensitive
// @desc Check if a string starts/ends with the specified prefix
@ -1029,11 +1024,13 @@ DQN_API Dqn_usize Dqn_CString16_Size (wcha
// @proc Dqn_String8 Dqn_String8_BinarySplit
// @desc @see Dqn_CString8_BinarySplit
//
// @proc Dqn_String8_Eq
// @desc @see Dqn_CString8_Eq
//
// @proc Dqn_String8_EqInsensitive
// @desc @see Dqn_CString8_EqInsensitive
// @proc Dqn_String8_Eq, Dqn_String8_EqInsensitive
// @desc Compare a string for equality with or without case sensitivity.
// @param[in] lhs The first string to compare equality with
// @param[in] rhs The second string to compare equality with
// @param[in] eq_case Set the comparison to be case sensitive or insensitive
// @return True if the arguments are valid, non-null and the strings
// are equal, false otherwise.
//
// @proc Dqn_String8_StartsWith
// @desc @see Dqn_CString8_StartsWith
@ -1165,6 +1162,7 @@ enum Dqn_String8EqCase
Dqn_String8EqCase_Insensitive,
};
DQN_API Dqn_String8 Dqn_String8_InitCString8 (char const *src);
DQN_API bool Dqn_String8_IsValid (Dqn_String8 string);
DQN_API bool Dqn_String8_IsAll (Dqn_String8 string, Dqn_String8IsAll is_all);
@ -1225,33 +1223,100 @@ enum Dqn_PrintStd
Dqn_PrintStd_Err,
};
DQN_API void Dqn_Print_Std(Dqn_PrintStd std_handle, Dqn_String8 string);
DQN_API void Dqn_Print_StdFV(Dqn_PrintStd std_handle, char const *fmt, va_list args);
DQN_API void Dqn_Print_StdF(Dqn_PrintStd std_handle, char const *fmt, ...);
enum Dqn_PrintBold
{
Dqn_PrintBold_No,
Dqn_PrintBold_Yes,
};
DQN_API void Dqn_Print_StdLn(Dqn_PrintStd std_handle, Dqn_String8 string);
DQN_API void Dqn_Print_StdLnFV(Dqn_PrintStd std_handle, char const *fmt, va_list args);
DQN_API void Dqn_Print_StdLnF(Dqn_PrintStd std_handle, char const *fmt, ...);
struct Dqn_PrintStyle
{
Dqn_PrintBold bold;
bool colour;
uint8_t r, g, b;
};
enum Dqn_PrintESCColour
{
Dqn_PrintESCColour_Fg,
Dqn_PrintESCColour_Bg,
};
// NOTE: Print Style ===============================================================================
DQN_API Dqn_PrintStyle Dqn_Print_StyleColour (uint8_t r, uint8_t g, uint8_t b, Dqn_PrintBold bold);
DQN_API Dqn_PrintStyle Dqn_Print_StyleColourU32 (uint32_t rgb, Dqn_PrintBold bold);
DQN_API Dqn_PrintStyle Dqn_Print_StyleBold ();
// NOTE: Print Standard Out ========================================================================
#define Dqn_Print(string) Dqn_Print_Std(Dqn_PrintStd_Out, string)
#define Dqn_Print_FV(fmt, args) Dqn_Print_StdFV(Dqn_PrintStd_Out, fmt, args)
#define Dqn_Print_F(fmt, ...) Dqn_Print_StdF(Dqn_PrintStd_Out, fmt, ## __VA_ARGS__)
#define Dqn_Print_FV(fmt, args) Dqn_Print_StdFV(Dqn_PrintStd_Out, fmt, args)
#define Dqn_Print_Style(style, string) Dqn_Print_StdStyle(Dqn_PrintStd_Out, style, string)
#define Dqn_Print_FStyle(style, fmt, ...) Dqn_Print_StdFStyle(Dqn_PrintStd_Out, style, fmt, ## __VA_ARGS__)
#define Dqn_Print_FVStyle(style, fmt, args, ...) Dqn_Print_StdFVStyle(Dqn_PrintStd_Out, style, fmt, args)
#define Dqn_Print_Ln(string) Dqn_Print_StdLn(Dqn_PrintStd_Out, string)
#define Dqn_Print_LnFV(fmt, args) Dqn_Print_StdLnFV(Dqn_PrintStd_Out, fmt, args)
#define Dqn_Print_LnF(fmt, ...) Dqn_Print_StdLnF(Dqn_PrintStd_Out, fmt, ## __VA_ARGS__)
#define Dqn_Print_LnFV(fmt, args) Dqn_Print_StdLnFV(Dqn_PrintStd_Out, fmt, args)
#define Dqn_Print_LnStyle(style, string) Dqn_Print_StdLnStyle(Dqn_PrintStd_Out, style, string);
#define Dqn_Print_LnFStyle(style, fmt, ...) Dqn_Print_StdLnFStyle(Dqn_PrintStd_Out, style, fmt, ## __VA_ARGS__);
#define Dqn_Print_LnFVStyle(style, fmt, args) Dqn_Print_StdLnFVStyle(Dqn_PrintStd_Out, style, fmt, args);
// NOTE: Print =====================================================================================
DQN_API void Dqn_Print_Std (Dqn_PrintStd std_handle, Dqn_String8 string);
DQN_API void Dqn_Print_StdF (Dqn_PrintStd std_handle, char const *fmt, ...);
DQN_API void Dqn_Print_StdFV (Dqn_PrintStd std_handle, char const *fmt, va_list args);
DQN_API void Dqn_Print_StdStyle (Dqn_PrintStd std_handle, Dqn_PrintStyle style, Dqn_String8 string);
DQN_API void Dqn_Print_StdFStyle (Dqn_PrintStd std_handle, Dqn_PrintStyle style, char const *fmt, ...);
DQN_API void Dqn_Print_StdFVStyle (Dqn_PrintStd std_handle, Dqn_PrintStyle style, char const *fmt, va_list args);
DQN_API void Dqn_Print_StdLn (Dqn_PrintStd std_handle, Dqn_String8 string);
DQN_API void Dqn_Print_StdLnF (Dqn_PrintStd std_handle, char const *fmt, ...);
DQN_API void Dqn_Print_StdLnFV (Dqn_PrintStd std_handle, char const *fmt, va_list args);
DQN_API void Dqn_Print_StdLnStyle (Dqn_PrintStd std_handle, Dqn_PrintStyle style, Dqn_String8 string);
DQN_API void Dqn_Print_StdLnFStyle (Dqn_PrintStd std_handle, Dqn_PrintStyle style, char const *fmt, ...);
DQN_API void Dqn_Print_StdLnFVStyle (Dqn_PrintStd std_handle, Dqn_PrintStyle style, char const *fmt, va_list args);
// NOTE: ANSI Formatting Codes =====================================================================
Dqn_String8 Dqn_Print_ESCColourString (Dqn_PrintESCColour colour, uint8_t r, uint8_t g, uint8_t b);
Dqn_String8 Dqn_Print_ESCColourU32String(Dqn_PrintESCColour colour, uint32_t value);
#define Dqn_Print_ESCColourFgString(r, g, b) Dqn_Print_ESCColourString(Dqn_PrintESCColour_Fg, r, g, b)
#define Dqn_Print_ESCColourBgString(r, g, b) Dqn_Print_ESCColourString(Dqn_PrintESCColour_Bg, r, g, b)
#define Dqn_Print_ESCColourFg(r, g, b) Dqn_Print_ESCColourString(Dqn_PrintESCColour_Fg, r, g, b).data
#define Dqn_Print_ESCColourBg(r, g, b) Dqn_Print_ESCColourString(Dqn_PrintESCColour_Bg, r, g, b).data
#define Dqn_Print_ESCColourFgU32String(value) Dqn_Print_ESCColourU32String(Dqn_PrintESCColour_Fg, value)
#define Dqn_Print_ESCColourBgU32String(value) Dqn_Print_ESCColourU32String(Dqn_PrintESCColour_Bg, value)
#define Dqn_Print_ESCColourFgU32(value) Dqn_Print_ESCColourU32String(Dqn_PrintESCColour_Fg, value).data
#define Dqn_Print_ESCColourBgU32(value) Dqn_Print_ESCColourU32String(Dqn_PrintESCColour_Bg, value).data
#define Dqn_Print_ESCReset "\x1b[0m"
#define Dqn_Print_ESCBold "\x1b[1m"
#define Dqn_Print_ESCResetString DQN_STRING8(Dqn_Print_ESCReset)
#define Dqn_Print_ESCBoldString DQN_STRING8(Dqn_Print_ESCBold)
// =================================================================================================
// [$LLOG] Dqn_Log | | Library logging
// =================================================================================================
enum Dqn_LogType
{
Dqn_LogType_Error,
Dqn_LogType_Debug,
Dqn_LogType_Info,
Dqn_LogType_Warning,
Dqn_LogType_Debug,
Dqn_LogType_Error,
Dqn_LogType_Count,
};
/// RGBA
#define Dqn_LogTypeColourU32_Info 0x00'87'ff'ff // Blue
#define Dqn_LogTypeColourU32_Warning 0xff'ff'00'ff // Yellow
#define Dqn_LogTypeColourU32_Error 0xff'00'00'ff // Red
/// The logging procedure of the library. Users can override the default logging
/// function by setting the logging function pointer in Dqn_Library. This
/// function will be invoked every time a log is recorded using the following
@ -1262,18 +1327,21 @@ enum Dqn_LogType
/// one of the default categories.
typedef void Dqn_LogProc(Dqn_String8 type, int log_type, void *user_data, Dqn_CallSite call_site, char const *fmt, va_list va);
#define Dqn_Log_ErrorF(fmt, ...) Dqn_Log_TypeFCallSite(Dqn_LogType_Error, DQN_CALL_SITE, fmt, ## __VA_ARGS__)
#define Dqn_Log_DebugF(fmt, ...) Dqn_Log_TypeFCallSite(Dqn_LogType_Debug, DQN_CALL_SITE, fmt, ## __VA_ARGS__)
#define Dqn_Log_WarningF(fmt, ...) Dqn_Log_TypeFCallSite(Dqn_LogType_Warning, DQN_CALL_SITE, fmt, ## __VA_ARGS__)
#define Dqn_Log_InfoF(fmt, ...) Dqn_Log_TypeFCallSite(Dqn_LogType_Info, DQN_CALL_SITE, fmt, ## __VA_ARGS__)
#define Dqn_Log_WarningF(fmt, ...) Dqn_Log_TypeFCallSite(Dqn_LogType_Warning, DQN_CALL_SITE, fmt, ## __VA_ARGS__)
#define Dqn_Log_ErrorF(fmt, ...) Dqn_Log_TypeFCallSite(Dqn_LogType_Error, DQN_CALL_SITE, fmt, ## __VA_ARGS__)
#define Dqn_Log_ErrorFV(fmt, args) Dqn_Log_TypeFVCallSite(Dqn_LogType_Error, DQN_CALL_SITE, fmt, args)
#define Dqn_Log_DebugFV(fmt, args) Dqn_Log_TypeFVCallSite(Dqn_LogType_Debug, DQN_CALL_SITE, fmt, args)
#define Dqn_Log_WarningFV(fmt, args) Dqn_Log_TypeFVCallSite(Dqn_LogType_Warning, DQN_CALL_SITE, fmt, args)
#define Dqn_Log_InfoFV(fmt, args) Dqn_Log_TypeFVCallSite(Dqn_LogType_Info, DQN_CALL_SITE, fmt, args)
#define Dqn_Log_WarningFV(fmt, args) Dqn_Log_TypeFVCallSite(Dqn_LogType_Warning, DQN_CALL_SITE, fmt, args)
#define Dqn_Log_ErrorFV(fmt, args) Dqn_Log_TypeFVCallSite(Dqn_LogType_Error, DQN_CALL_SITE, fmt, args)
#define Dqn_Log_TypeFV(type, fmt, args) Dqn_Log_TypeFVCallSite(type, DQN_CALL_SITE, fmt, args)
#define Dqn_Log_TypeF(type, fmt, ...) Dqn_Log_TypeFCallSite(type, DQN_CALL_SITE, fmt, ## __VA_ARGS__)
#define Dqn_Log_FV(type, fmt, args) Dqn_Log_FVCallSite(type, DQN_CALL_SITE, fmt, args)
#define Dqn_Log_F(type, fmt, ...) Dqn_Log_FVCallSite(type, fmt, ## __VA_ARGS__)
#define Dqn_Log_F(type, fmt, ...) Dqn_Log_FCallSite(type, DQN_CALL_SITE, fmt, ## __VA_ARGS__)
DQN_API void Dqn_Log_TypeFVCallSite(Dqn_LogType type, Dqn_CallSite call_site, char const *fmt, va_list va);
DQN_API void Dqn_Log_TypeFCallSite (Dqn_LogType type, Dqn_CallSite call_site, char const *fmt, ...);
@ -1948,18 +2016,18 @@ DQN_API void Dqn_Library_LeakTraceMarkFree (Dqn_CallSite call_site, void
// @return String referencing the contents of `string`
//
// @proc Dqn_FString8_Eq
// @desc @see Dqn_CString8_Eq
// @desc @see Dqn_String8_Eq
//
// @proc Dqn_FString8_EqString8
// @desc @see Dqn_CString8_Eq
// @desc @see Dqn_String8_Eq
//
// @proc Dqn_FString8_EqInsensitive
// @desc Compare a string for equality, case insensitive
// @see Dqn_CString8_Eq
// @see Dqn_String8_Eq
//
// @proc Dqn_FString8_EqString8Insensitive
// @desc Compare a string for equality, case insensitive
// @see Dqn_CString8_Eq
// @see Dqn_String8_Eq
template <Dqn_usize N> struct Dqn_FString8
{
@ -3951,13 +4019,13 @@ template <Dqn_usize N> Dqn_FString8<N> Dqn_FString8_InitF(char const *fmt, ...)
template <Dqn_usize N> Dqn_usize Dqn_FString8_Max(Dqn_FString8<N> const *)
{
Dqn_usize result = MAX_;
Dqn_usize result = N;
return result;
}
template <Dqn_usize N> void Dqn_FString8_Clear(Dqn_FString8<N> *string)
{
*str = {};
*string = {};
}
template <Dqn_usize N> bool Dqn_FString8_AppendFV(Dqn_FString8<N> *string, char const *fmt, va_list args)
@ -4027,13 +4095,16 @@ template <Dqn_usize N> Dqn_String8 Dqn_FString8_ToString8(Dqn_FString8<N> const
template <Dqn_usize N> bool Dqn_FString8_Eq(Dqn_FString8<N> const *lhs, Dqn_FString8<N> const *rhs, Dqn_String8EqCase eq_case)
{
bool result = Dqn_CString8_Eq(lhs->data, rhs->data, lhs->size, rhs->size, eq_case);
Dqn_String8 lhs_s8 = Dqn_FString8_ToString8(lhs);
Dqn_String8 rhs_s8 = Dqn_FString8_ToString8(rhs);
bool result = Dqn_String8_Eq(lhs_s8, rhs_s8, eq_case);
return result;
}
template <Dqn_usize N> bool Dqn_FString8_EqString8(Dqn_FString8<N> const *lhs, Dqn_String8 rhs, Dqn_String8EqCase eq_case)
{
bool result = Dqn_CString8_Eq(lhs->data, rhs.data, lhs->size, rhs.size, eq_case);
Dqn_String8 lhs_s8 = Dqn_FString8_ToString8(lhs);
bool result = Dqn_String8_Eq(lhs_s8, rhs, eq_case);
return result;
}
@ -4064,7 +4135,7 @@ template <Dqn_usize A, Dqn_usize B> bool Dqn_FString8_EqFString8Insensitive(Dqn_
{
Dqn_String8 lhs_s8 = Dqn_FString8_ToString8(lhs);
Dqn_String8 rhs_s8 = Dqn_FString8_ToString8(rhs);
bool result = Dqn_CString8_Eq(lhs_s8, rhs_s8, Dqn_String8EqCase_Insensitive);
bool result = Dqn_String8_Eq(lhs_s8, rhs_s8, Dqn_String8EqCase_Insensitive);
return result;
}
#endif // !defined(DQN_NO_FSTRING8)
@ -4799,39 +4870,52 @@ DQN_FILE_SCOPE void Dqn_Log_FVDefault_(Dqn_String8 type, int log_type, void *use
// NOTE: Generate the log header
// =========================================================================
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(nullptr);
Dqn_usize header_size_no_ansi_codes = 0;
Dqn_String8 header = {};
{
DQN_LOCAL_PERSIST Dqn_usize max_type_length = 0;
max_type_length = DQN_MAX(max_type_length, type.size);
int type_padding = DQN_CAST(int)(max_type_length - type.size);
Dqn_String8 colour = {};
switch (log_type) {
case Dqn_LogType_Debug: break;
case Dqn_LogType_Info: colour = Dqn_Print_ESCColourFgU32String(Dqn_LogTypeColourU32_Info); break;
case Dqn_LogType_Warning: colour = Dqn_Print_ESCColourFgU32String(Dqn_LogTypeColourU32_Warning); break;
case Dqn_LogType_Error: colour = Dqn_Print_ESCColourFgU32String(Dqn_LogTypeColourU32_Error); break;
}
Dqn_String8 file_name = Dqn_String8_FileNameFromPath(call_site.file);
Dqn_DateHMSTimeString const time = Dqn_Date_HMSLocalTimeStringNow();
header = Dqn_String8_InitF(scratch.allocator, "%.*s %.*s %.*s %.*s %05u %.*s: ",
time.date_size - 2,
time.date + 2,
time.hms_size,
time.hms,
DQN_STRING_FMT(type),
DQN_STRING_FMT(file_name),
call_site.line,
DQN_STRING_FMT(call_site.function));
header = Dqn_String8_InitF(scratch.allocator,
"%.*s %.*s " Dqn_Print_ESCBold "%.*s%.*s%*s" Dqn_Print_ESCReset " %.*s:%05u ",
time.date_size - 2, time.date + 2,
time.hms_size, time.hms,
colour.size, colour.data,
type.size, type.data,
type_padding, "",
file_name.size, file_name.data,
call_site.line);
header_size_no_ansi_codes = header.size - colour.size - Dqn_Print_ESCResetString.size;
}
// NOTE: Header padding
// =========================================================================
Dqn_usize padding_size = 0;
Dqn_usize header_padding = 0;
{
DQN_LOCAL_PERSIST Dqn_usize max_header_length = 0;
max_header_length = DQN_MAX(max_header_length, header.size);
padding_size = max_header_length - header.size;
max_header_length = DQN_MAX(max_header_length, header_size_no_ansi_codes);
header_padding = max_header_length - header_size_no_ansi_codes;
}
// NOTE: Construct final log
// =========================================================================
Dqn_String8 msg = Dqn_String8_InitFV(scratch.allocator, fmt, args);
Dqn_String8 log_line = Dqn_String8_Allocate(scratch.allocator, header.size + padding_size + msg.size, Dqn_ZeroMem_No);
Dqn_String8 log_line = Dqn_String8_Allocate(scratch.allocator, header.size + header_padding + msg.size, Dqn_ZeroMem_No);
DQN_MEMCPY(log_line.data, header.data, header.size);
DQN_MEMSET(log_line.data + header.size, ' ', padding_size);
DQN_MEMCPY(log_line.data + header.size + padding_size, msg.data, msg.size);
DQN_MEMSET(log_line.data + header.size, ' ', header_padding);
DQN_MEMCPY(log_line.data + header.size + header_padding, msg.data, msg.size);
// NOTE: Print log
// =========================================================================
@ -4861,12 +4945,11 @@ DQN_API void Dqn_Log_FCallSite(Dqn_String8 type, Dqn_CallSite call_site, char co
DQN_API void Dqn_Log_TypeFVCallSite(Dqn_LogType type, Dqn_CallSite call_site, char const *fmt, va_list args)
{
Dqn_String8 type_string = DQN_STRING8("DQN-BAD-LOG-TYPE");
switch (type)
{
case Dqn_LogType_Error: type_string = DQN_STRING8("ERROR");
case Dqn_LogType_Info: type_string = DQN_STRING8("INFO");
case Dqn_LogType_Warning: type_string = DQN_STRING8("WARN");
case Dqn_LogType_Debug: type_string = DQN_STRING8("DEBUG");
switch (type) {
case Dqn_LogType_Error: type_string = DQN_STRING8("ERROR"); break;
case Dqn_LogType_Info: type_string = DQN_STRING8("INFO"); break;
case Dqn_LogType_Warning: type_string = DQN_STRING8("WARN"); break;
case Dqn_LogType_Debug: type_string = DQN_STRING8("DEBUG"); break;
}
Dqn_LogProc *logging_function = dqn_library.log_callback ? dqn_library.log_callback : Dqn_Log_FVDefault_;
@ -4984,6 +5067,13 @@ DQN_API Dqn_usize Dqn_CString16_Size(wchar_t const *src)
// =================================================================================================
// [$STR8] Dqn_String8 | | Pointer and length strings
// =================================================================================================
DQN_API Dqn_String8 Dqn_String8_InitCString8(char const *src)
{
Dqn_usize size = Dqn_CString8_Size(src);
Dqn_String8 result = Dqn_String8_Init(src, size);
return result;
}
DQN_API bool Dqn_String8_IsValid(Dqn_String8 string)
{
bool result = string.data;
@ -5339,19 +5429,18 @@ DQN_API Dqn_String8 Dqn_String8_Replace(Dqn_String8 string,
Dqn_String8 find,
Dqn_String8 replace,
Dqn_usize start_index,
Dqn_Arena *arena,
Dqn_Arena *temp_arena,
Dqn_Allocator allocator,
Dqn_String8EqCase eq_case)
{
Dqn_String8 result = {};
if (!Dqn_String8_IsValid(string) || !Dqn_String8_IsValid(find) || find.size > string.size || find.size == 0 || string.size == 0) {
result = Dqn_String8_Copy(Dqn_Arena_Allocator(arena), string);
result = Dqn_String8_Copy(allocator, string);
return result;
}
auto temp_arena_scope = Dqn_ArenaTempMemoryScope(temp_arena);
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(allocator.user_context);
Dqn_String8Builder string_builder = {};
string_builder.allocator = Dqn_Arena_Allocator(temp_arena);
string_builder.allocator = scratch.allocator;
Dqn_usize max = string.size - find.size;
Dqn_usize head = start_index;
@ -5378,19 +5467,19 @@ DQN_API Dqn_String8 Dqn_String8_Replace(Dqn_String8 string,
if (string_builder.string_size == 0) {
// NOTE: No replacement possible, so we just do a full-copy
result = Dqn_String8_Copy(Dqn_Arena_Allocator(arena), string);
result = Dqn_String8_Copy(allocator, string);
} else {
Dqn_String8 remainder = Dqn_String8_Init(string.data + head, string.size - head);
Dqn_String8Builder_AppendRef(&string_builder, remainder);
result = Dqn_String8Builder_Build(&string_builder, Dqn_Arena_Allocator(arena));
result = Dqn_String8Builder_Build(&string_builder, allocator);
}
return result;
}
DQN_API Dqn_String8 Dqn_String8_ReplaceInsensitive(Dqn_String8 string, Dqn_String8 find, Dqn_String8 replace, Dqn_usize start_index, Dqn_Arena *arena, Dqn_Arena *temp_arena)
DQN_API Dqn_String8 Dqn_String8_ReplaceInsensitive(Dqn_String8 string, Dqn_String8 find, Dqn_String8 replace, Dqn_usize start_index, Dqn_Allocator allocator)
{
Dqn_String8 result = Dqn_String8_Replace(string, find, replace, start_index, arena, temp_arena, Dqn_String8EqCase_Insensitive);
Dqn_String8 result = Dqn_String8_Replace(string, find, replace, start_index, allocator, Dqn_String8EqCase_Insensitive);
return result;
}
@ -5477,6 +5566,33 @@ DQN_API Dqn_String8 Dqn_String8_Copy_(DQN_LEAK_TRACE_FUNCTION Dqn_Allocator allo
// =================================================================================================
// [$PRIN] Dqn_Print | | Printing
// =================================================================================================
DQN_API Dqn_PrintStyle Dqn_Print_StyleColour(uint8_t r, uint8_t g, uint8_t b, Dqn_PrintBold bold)
{
Dqn_PrintStyle result = {};
result.bold = bold;
result.colour = true;
result.r = r;
result.g = g;
result.b = b;
return result;
}
DQN_API Dqn_PrintStyle Dqn_Print_StyleColourU32(uint32_t rgb, Dqn_PrintBold bold)
{
uint8_t r = (rgb >> 24) & 0xFF;
uint8_t g = (rgb >> 16) & 0xFF;
uint8_t b = (rgb >> 8) & 0xFF;
Dqn_PrintStyle result = Dqn_Print_StyleColour(r, g, b, bold);
return result;
}
DQN_API Dqn_PrintStyle Dqn_Print_StyleBold()
{
Dqn_PrintStyle result = {};
result.bold = Dqn_PrintBold_Yes;
return result;
}
DQN_API void Dqn_Print_Std(Dqn_PrintStd std_handle, Dqn_String8 string)
{
DQN_ASSERT(std_handle == Dqn_PrintStd_Out || std_handle == Dqn_PrintStd_Err);
@ -5521,6 +5637,19 @@ DQN_API void Dqn_Print_Std(Dqn_PrintStd std_handle, Dqn_String8 string)
#endif
}
DQN_API void Dqn_Print_StdStyle(Dqn_PrintStd std_handle, Dqn_PrintStyle style, Dqn_String8 string)
{
if (string.data && string.size) {
if (style.colour)
Dqn_Print_Std(std_handle, Dqn_Print_ESCColourFgString(style.r, style.g, style.b));
if (style.bold == Dqn_PrintBold_Yes)
Dqn_Print_Std(std_handle, Dqn_Print_ESCBoldString);
Dqn_Print_Std(std_handle, string);
if (style.colour || style.bold == Dqn_PrintBold_Yes)
Dqn_Print_Std(std_handle, Dqn_Print_ESCResetString);
}
}
DQN_FILE_SCOPE char *Dqn_Print_VSPrintfChunker_(const char *buf, void *user, int len)
{
Dqn_String8 string = {};
@ -5532,12 +5661,6 @@ DQN_FILE_SCOPE char *Dqn_Print_VSPrintfChunker_(const char *buf, void *user, int
return (char *)buf;
}
DQN_API void Dqn_Print_StdFV(Dqn_PrintStd std_handle, char const *fmt, va_list args)
{
char buffer[STB_SPRINTF_MIN];
STB_SPRINTF_DECORATE(vsprintfcb)(Dqn_Print_VSPrintfChunker_, DQN_CAST(void *)DQN_CAST(uintptr_t)std_handle, buffer, fmt, args);
}
DQN_API void Dqn_Print_StdF(Dqn_PrintStd std_handle, char const *fmt, ...)
{
va_list args;
@ -5546,18 +5669,39 @@ DQN_API void Dqn_Print_StdF(Dqn_PrintStd std_handle, char const *fmt, ...)
va_end(args);
}
DQN_API void Dqn_Print_StdFStyle(Dqn_PrintStd std_handle, Dqn_PrintStyle style, char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
Dqn_Print_StdFVStyle(std_handle, style, fmt, args);
va_end(args);
}
DQN_API void Dqn_Print_StdFV(Dqn_PrintStd std_handle, char const *fmt, va_list args)
{
char buffer[STB_SPRINTF_MIN];
STB_SPRINTF_DECORATE(vsprintfcb)(Dqn_Print_VSPrintfChunker_, DQN_CAST(void *)DQN_CAST(uintptr_t)std_handle, buffer, fmt, args);
}
DQN_API void Dqn_Print_StdFVStyle(Dqn_PrintStd std_handle, Dqn_PrintStyle style, char const *fmt, va_list args)
{
if (fmt) {
if (style.colour)
Dqn_Print_Std(std_handle, Dqn_Print_ESCColourFgString(style.r, style.g, style.b));
if (style.bold == Dqn_PrintBold_Yes)
Dqn_Print_Std(std_handle, Dqn_Print_ESCBoldString);
Dqn_Print_StdFV(std_handle, fmt, args);
if (style.colour || style.bold == Dqn_PrintBold_Yes)
Dqn_Print_Std(std_handle, Dqn_Print_ESCResetString);
}
}
DQN_API void Dqn_Print_StdLn(Dqn_PrintStd std_handle, Dqn_String8 string)
{
Dqn_Print_Std(std_handle, string);
Dqn_Print_Std(std_handle, DQN_STRING8("\n"));
}
DQN_API void Dqn_Print_StdLnFV(Dqn_PrintStd std_handle, char const *fmt, va_list args)
{
Dqn_Print_StdFV(std_handle, fmt, args);
Dqn_Print_Std(std_handle, DQN_STRING8("\n"));
}
DQN_API void Dqn_Print_StdLnF(Dqn_PrintStd std_handle, char const *fmt, ...)
{
va_list args;
@ -5566,6 +5710,55 @@ DQN_API void Dqn_Print_StdLnF(Dqn_PrintStd std_handle, char const *fmt, ...)
va_end(args);
}
DQN_API void Dqn_Print_StdLnFV(Dqn_PrintStd std_handle, char const *fmt, va_list args)
{
Dqn_Print_StdFV(std_handle, fmt, args);
Dqn_Print_Std(std_handle, DQN_STRING8("\n"));
}
DQN_API void Dqn_Print_StdLnStyle(Dqn_PrintStd std_handle, Dqn_PrintStyle style, Dqn_String8 string)
{
Dqn_Print_StdStyle(std_handle, style, string);
Dqn_Print_Std(std_handle, DQN_STRING8("\n"));
}
DQN_API void Dqn_Print_StdLnFStyle(Dqn_PrintStd std_handle, Dqn_PrintStyle style, char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
Dqn_Print_StdLnFVStyle(std_handle, style, fmt, args);
va_end(args);
}
DQN_API void Dqn_Print_StdLnFVStyle(Dqn_PrintStd std_handle, Dqn_PrintStyle style, char const *fmt, va_list args)
{
Dqn_Print_StdFVStyle(std_handle, style, fmt, args);
Dqn_Print_Std(std_handle, DQN_STRING8("\n"));
}
DQN_API Dqn_String8 Dqn_Print_ESCColourString(Dqn_PrintESCColour colour, uint8_t r, uint8_t g, uint8_t b)
{
thread_local char buffer[32];
buffer[0] = 0;
Dqn_String8 result = {};
result.size = STB_SPRINTF_DECORATE(snprintf)(buffer,
DQN_ARRAY_UCOUNT(buffer),
"\x1b[%d;2;%u;%u;%um",
colour == Dqn_PrintESCColour_Fg ? 38 : 48,
r, g, b);
result.data = buffer;
return result;
}
DQN_API Dqn_String8 Dqn_Print_ESCColourU32String(Dqn_PrintESCColour colour, uint32_t value)
{
uint8_t r = DQN_CAST(uint8_t)(value >> 24);
uint8_t g = DQN_CAST(uint8_t)(value >> 16);
uint8_t b = DQN_CAST(uint8_t)(value >> 8);
Dqn_String8 result = Dqn_Print_ESCColourString(colour, r, g, b);
return result;
}
#if !defined(DQN_NO_DSMAP)
// =================================================================================================
// [$DMAP] Dqn_DSMap | DQN_NO_DSMAP | Hashtable, 70% max load, PoT size, linear probe, chain repair
@ -5689,7 +5882,7 @@ DQN_API void Dqn_Library_DumpThreadContextArenaStat(Dqn_String8 file_path)
}
fclose(file);
DQN_LOG_I("Dumped thread context arenas [file=%.*s]", DQN_STRING_FMT(file_path));
Dqn_Log_InfoF("Dumped thread context arenas [file=%.*s]", DQN_STRING_FMT(file_path));
#else
(void)file_path;
#endif // #if defined(DQN_DEBUG_THREAD_CONTEXT)
@ -5845,7 +6038,7 @@ DQN_API void Dqn_Arena_CommitFromBlock(Dqn_ArenaBlock *block, Dqn_usize size, Dq
} break;
case Dqn_ArenaCommit_EnsureSpace: {
DQN_ASSERT(block->commit > block->used);
DQN_ASSERT(block->commit >= block->used);
Dqn_usize const unused_commit_space = block->commit - block->used;
if (unused_commit_space < size)
commit_size = Dqn_PowerOfTwoAlign(size - unused_commit_space, DQN_KILOBYTES(4));

View File

@ -41,7 +41,7 @@ struct Dqn_JSONIterator
bool Dqn_JSON_IteratorPushObjElement (Dqn_JSONIterator *it, json_object_element_s *element);
bool Dqn_JSON_IteratorPushObj (Dqn_JSONIterator *it, json_object_s *obj);
bool Dqn_JSON_IteratorPushArrayElement(Dqn_JSONIterator *it, json_array_element_s *element);
bool Dqn_JSON_IteratorPushArray (Dqn_JSONIterator *it, json_array_s *array);
bool Dqn_JSON_IteratorPushArray (Dqn_JSONIterator *it, json_value_s *value);
bool Dqn_JSON_IteratorPushValue (Dqn_JSONIterator *it, json_value_s *value);
void Dqn_JSON_IteratorPop (Dqn_JSONIterator *it);
@ -166,12 +166,12 @@ bool Dqn_JSON_IteratorPushArrayElement(Dqn_JSONIterator *it, json_array_element_
return true;
}
bool Dqn_JSON_IteratorPushArray(Dqn_JSONIterator *it, json_array_s *array)
bool Dqn_JSON_IteratorPushArray(Dqn_JSONIterator *it, json_value_s *value)
{
if (!it || !array)
if (!it || !value || json_value_as_array(value) == nullptr)
return false;
DQN_ASSERT(it->stack_count < DQN_ARRAY_ICOUNT(it->stack));
it->stack[it->stack_count++] = {Dqn_JSON_IteratorEntryTypeArray, array};
it->stack[it->stack_count++] = {Dqn_JSON_IteratorEntryTypeArray, value};
return true;
}
@ -184,7 +184,7 @@ bool Dqn_JSON_IteratorPushValue(Dqn_JSONIterator *it, json_value_s *value)
if (value->type == json_type_object) {
result = Dqn_JSON_IteratorPushObj(it, json_value_as_object(value));
} else if (value->type == json_type_array) {
result = Dqn_JSON_IteratorPushArray(it, json_value_as_array(value));
result = Dqn_JSON_IteratorPushArray(it, value);
}
return result;
@ -221,7 +221,7 @@ json_value_s *Dqn_JSON_IteratorPushCurrValue(Dqn_JSONIterator *it)
if (result->type == json_type_array) {
json_array_s *array = json_value_as_array(result);
DQN_ASSERT(array);
Dqn_JSON_IteratorPushArray(it, array);
Dqn_JSON_IteratorPushArray(it, result);
} else if (result->type == json_type_object) {
json_object_s *obj = json_value_as_object(result);
DQN_ASSERT(obj);
@ -247,7 +247,8 @@ bool Dqn_JSON_IteratorNext(Dqn_JSONIterator *it)
obj_element = element->next;
Dqn_JSON_IteratorPop(it);
} else if (curr->type == Dqn_JSON_IteratorEntryTypeArray) {
auto *array = DQN_CAST(json_array_s *) curr->value;
auto *value = DQN_CAST(json_value_s *) curr->value;
auto *array = json_value_as_array(value);
array_element = array->start;
} else if (curr->type == Dqn_JSON_IteratorEntryTypeArrayElement) {
auto *element = DQN_CAST(json_array_element_s *) curr->value;