Add printf-like log function backed by String_Builder.
This commit is contained in:
parent
1a2de6e2f8
commit
a29b67e524
2
.gitignore
vendored
2
.gitignore
vendored
@ -3,6 +3,8 @@
|
|||||||
##
|
##
|
||||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||||
|
|
||||||
|
.stfolder/
|
||||||
|
|
||||||
# User-specific files
|
# User-specific files
|
||||||
*.suo
|
*.suo
|
||||||
*.user
|
*.user
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
|
|
||||||
#define ALLOCATOR_DEBUG_MODE 0
|
#define ALLOCATOR_DEBUG_MODE 1
|
||||||
#define ALLOCATOR_POISON_MEMORY_ON_ALLOCATION \
|
#define ALLOCATOR_POISON_MEMORY_ON_ALLOCATION \
|
||||||
(BUILD_DEBUG && ALLOCATOR_DEBUG_MODE)
|
(BUILD_DEBUG && ALLOCATOR_DEBUG_MODE)
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ struct Allocator {
|
|||||||
void* data;
|
void* data;
|
||||||
|
|
||||||
bool operator ! () {
|
bool operator ! () {
|
||||||
return (proc == nullptr && data == nullptr);
|
return (proc == nullptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,7 @@ global Array<Arena*> arenas_in_flight[6];
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void initialize_arena_table () {
|
void initialize_arena_table () {
|
||||||
|
// debug_break();
|
||||||
for (s32 i = 0; i < 6; i += 1) {
|
for (s32 i = 0; i < 6; i += 1) {
|
||||||
arena_free_table[i].allocator = GPAllocator();
|
arena_free_table[i].allocator = GPAllocator();
|
||||||
array_reserve(arena_free_table[i], 64);
|
array_reserve(arena_free_table[i], 64);
|
||||||
|
|||||||
@ -165,25 +165,27 @@ T pop (Array<T>& src) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename U>
|
// template <typename T, typename U>
|
||||||
void array_add (Array<T>& src, U new_item) {
|
// void array_add (Array<T>& src, U new_item) {
|
||||||
static_assert(sizeof(U) <= sizeof(T));
|
// static_assert(sizeof(U) <= sizeof(T));
|
||||||
auto new_count = src.count + 1;
|
// auto new_count = src.count + 1;
|
||||||
array_maybe_grow(src);
|
// array_maybe_grow(src);
|
||||||
|
|
||||||
T new_item_casted = (T)new_item;
|
// T new_item_casted = (T)new_item;
|
||||||
|
|
||||||
src.count += 1;
|
// src.count += 1;
|
||||||
memcpy(&src[src.count-1], &new_item_casted, sizeof(T));
|
// memcpy(&src[src.count-1], &new_item_casted, sizeof(T));
|
||||||
}
|
// }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void array_add (Array<T>& src, T new_item) {
|
void array_add (Array<T>& src, T new_item) {
|
||||||
auto new_count = src.count + 1;
|
|
||||||
array_maybe_grow(src);
|
array_maybe_grow(src);
|
||||||
|
|
||||||
|
src.data[src.count] = new_item;
|
||||||
|
|
||||||
src.count += 1;
|
src.count += 1;
|
||||||
memcpy(&src[src.count-1], &new_item, sizeof(T));
|
// auto dst_ptr = &src.data[src.count-1];
|
||||||
|
// memcpy(dst_ptr, &new_item, sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
// See Context_Base in jai, and TCTX in raddebugger:
|
// See Context_Base in jai, and TCTX in raddebugger:
|
||||||
|
|
||||||
internal void Bootstrap_Main_Thread_Context () {
|
internal void Bootstrap_Main_Thread_Context () {
|
||||||
// 0. Setup general MB(70) allocator
|
// 0. Setup general allocator
|
||||||
GPAllocator_Initialize_Allocation_Tracker();
|
GPAllocator_Initialize_Allocation_Tracker();
|
||||||
// 1. Setup arena table
|
// 1. Setup arena table
|
||||||
initialize_arena_table();
|
initialize_arena_table();
|
||||||
@ -14,8 +14,10 @@ internal void Bootstrap_Main_Thread_Context () {
|
|||||||
thread_local_context->allocator = get_allocator(arena_ex);
|
thread_local_context->allocator = get_allocator(arena_ex);
|
||||||
thread_local_context->thread_idx = 0;
|
thread_local_context->thread_idx = 0;
|
||||||
thread_local_context->thread_name = "Main Thread";
|
thread_local_context->thread_name = "Main Thread";
|
||||||
// thread_local_context->logger = init_logger();
|
thread_local_context->log_builder = new_string_builder(Arena_Reserve::Size_64M);
|
||||||
|
|
||||||
|
default_logger_initialize();
|
||||||
|
thread_local_context->logger = {default_logger_proc, &default_logger};
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Push_Arena {
|
struct Push_Arena {
|
||||||
@ -43,25 +45,7 @@ struct Push_Arena {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Push_Allocator {
|
|
||||||
Thread_Context* context;
|
|
||||||
Allocator old_allocator;
|
|
||||||
|
|
||||||
Push_Allocator (Allocator new_allocator) {
|
|
||||||
context = get_thread_context();
|
|
||||||
old_allocator = context->allocator;
|
|
||||||
context->allocator = new_allocator;
|
|
||||||
}
|
|
||||||
|
|
||||||
~Push_Allocator () {
|
|
||||||
context->allocator = old_allocator;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Thread-local allocators:
|
// Thread-local allocators:
|
||||||
PROTOTYPING_API Allocator get_temp_allocator();
|
|
||||||
PROTOTYPING_API Allocator get_context_allocator();
|
|
||||||
|
|
||||||
// Start from w32_entry_point_caller ->
|
// Start from w32_entry_point_caller ->
|
||||||
// see main_thread_base_entry_point
|
// see main_thread_base_entry_point
|
||||||
@ -81,7 +65,11 @@ Thread_Context* get_thread_context () {
|
|||||||
return (Thread_Context*)thread_local_context;
|
return (Thread_Context*)thread_local_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
force_inline Allocator get_temp_allocator() {
|
Logger* get_context_logger () {
|
||||||
|
return &get_thread_context()->logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
force_inline Allocator get_temp_allocator () {
|
||||||
return get_allocator(get_thread_context()->temp);
|
return get_allocator(get_thread_context()->temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,8 @@ struct Thread_Context {
|
|||||||
s32 thread_idx;
|
s32 thread_idx;
|
||||||
u16 _padding0;
|
u16 _padding0;
|
||||||
u16 GPAllocator_alignment = 16;
|
u16 GPAllocator_alignment = 16;
|
||||||
// Logger logger;
|
Logger logger = {nullptr, nullptr};
|
||||||
|
String_Builder* log_builder;
|
||||||
// Stack_Trace* stack_trace;
|
// Stack_Trace* stack_trace;
|
||||||
|
|
||||||
Array<Thread*> child_threads; // maybe should be linked-list?
|
Array<Thread*> child_threads; // maybe should be linked-list?
|
||||||
@ -23,3 +24,18 @@ thread_static Thread_Context* thread_local_context;
|
|||||||
Thread_Context* get_thread_context ();
|
Thread_Context* get_thread_context ();
|
||||||
|
|
||||||
internal void Bootstrap_Main_Thread_Context ();
|
internal void Bootstrap_Main_Thread_Context ();
|
||||||
|
|
||||||
|
struct Push_Allocator {
|
||||||
|
Thread_Context* context;
|
||||||
|
Allocator old_allocator;
|
||||||
|
|
||||||
|
Push_Allocator (Allocator new_allocator) {
|
||||||
|
context = get_thread_context();
|
||||||
|
old_allocator = context->allocator;
|
||||||
|
context->allocator = new_allocator;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Push_Allocator () {
|
||||||
|
context->allocator = old_allocator;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@ -10,9 +10,12 @@
|
|||||||
#define Aligned_Realloc(old_sz, ptr, sz, align) _aligned_realloc_dbg(ptr, sz, align, __FILE__, __LINE__)
|
#define Aligned_Realloc(old_sz, ptr, sz, align) _aligned_realloc_dbg(ptr, sz, align, __FILE__, __LINE__)
|
||||||
#define Aligned_Free(ptr) _aligned_free_dbg(ptr)
|
#define Aligned_Free(ptr) _aligned_free_dbg(ptr)
|
||||||
#else
|
#else
|
||||||
#define Aligned_Alloc(sz, align) _aligned_malloc(sz, align)
|
#define Aligned_Alloc(sz, align) std::malloc(sz)//_aligned_malloc(sz, align)
|
||||||
#define Aligned_Realloc(old_sz, ptr, sz, align) _aligned_realloc(ptr, sz, align)
|
#define Aligned_Realloc(old_sz, ptr, sz, align) std::realloc(ptr, sz)//_aligned_realloc(ptr, sz, align)
|
||||||
#define Aligned_Free(ptr) _aligned_free(ptr)
|
#define Aligned_Free(ptr) std::free(ptr)//_aligned_free(ptr)
|
||||||
|
// #define Aligned_Alloc(sz, align) _aligned_malloc(sz, align)
|
||||||
|
// #define Aligned_Realloc(old_sz, ptr, sz, align) _aligned_realloc(ptr, sz, align)
|
||||||
|
// #define Aligned_Free(ptr) _aligned_free(ptr)
|
||||||
#endif
|
#endif
|
||||||
#else // Non-MSVC (POSIX / GCC / Clang)
|
#else // Non-MSVC (POSIX / GCC / Clang)
|
||||||
#include <cstdlib> // std::aligned_alloc
|
#include <cstdlib> // std::aligned_alloc
|
||||||
@ -20,7 +23,6 @@
|
|||||||
#define Aligned_Realloc(old_sz, ptr, sz, align) gp_aligned_realloc(old_sz, ptr, sz, align)
|
#define Aligned_Realloc(old_sz, ptr, sz, align) gp_aligned_realloc(old_sz, ptr, sz, align)
|
||||||
#define Aligned_Free(ptr) std::free(ptr)
|
#define Aligned_Free(ptr) std::free(ptr)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct Allocation {
|
struct Allocation {
|
||||||
s64 size;
|
s64 size;
|
||||||
void* memory;
|
void* memory;
|
||||||
|
|||||||
27
lib/Base/Logger.cpp
Normal file
27
lib/Base/Logger.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
void log (string fmt, ...) {
|
||||||
|
String_Builder* sb = get_thread_context()->log_builder;
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
print_to_builder(sb, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
// Append newline if needed
|
||||||
|
string result = string_view(sb);
|
||||||
|
bool ends_with_newline = (result.data[result.count-1] == '\n');
|
||||||
|
if (!ends_with_newline) {
|
||||||
|
append(sb, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
string message = string_view(sb);
|
||||||
|
|
||||||
|
Logger* logger = get_context_logger();
|
||||||
|
logger->proc(message, Log_Level::None, logger->data);
|
||||||
|
|
||||||
|
reset_string_builder(sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print (string message) {
|
||||||
|
Logger* logger = get_context_logger();
|
||||||
|
logger->proc(message, Log_Level::None, logger->data);
|
||||||
|
}
|
||||||
@ -4,7 +4,7 @@
|
|||||||
// See Logger.jai in our jiim-dev-gui project for how to do fancy colored text.
|
// See Logger.jai in our jiim-dev-gui project for how to do fancy colored text.
|
||||||
enum class Log_Level : s32 {
|
enum class Log_Level : s32 {
|
||||||
TODO = -2,
|
TODO = -2,
|
||||||
Trace = -1;
|
Trace = -1,
|
||||||
None = 0,
|
None = 0,
|
||||||
Info = 1,
|
Info = 1,
|
||||||
Warning = 2,
|
Warning = 2,
|
||||||
@ -12,5 +12,64 @@ enum class Log_Level : s32 {
|
|||||||
Fatal_Error = 4,
|
Fatal_Error = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
// log_function pointer
|
// log_function pointer
|
||||||
typedef void (*Logger_Proc)(string log_message, ...);
|
typedef void (*Logger_Proc)(string log_message, Log_Level level, void* data);
|
||||||
|
void default_logger_proc (string log_message, Log_Level level, void* data); //fwd declared
|
||||||
|
|
||||||
|
struct Logger {
|
||||||
|
Logger_Proc proc;
|
||||||
|
void* data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Default_Logger {
|
||||||
|
Logger_Proc proc = default_logger_proc;
|
||||||
|
String_Builder* sb = nullptr;
|
||||||
|
|
||||||
|
Mutex* mutex;
|
||||||
|
#if OS_WINDOWS
|
||||||
|
void* windows_standard_output;
|
||||||
|
void* windows_standard_error;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
global Default_Logger default_logger;
|
||||||
|
|
||||||
|
// default_logger_proc()...
|
||||||
|
#if OS_WINDOWS
|
||||||
|
void os_write_string_unsynchronized(string s, bool to_standard_error) {
|
||||||
|
u32 written = 0;
|
||||||
|
void* handle = (to_standard_error) ?
|
||||||
|
default_logger.windows_standard_error :
|
||||||
|
default_logger.windows_standard_output;
|
||||||
|
Assert(handle != nullptr);
|
||||||
|
bool result = (bool)WriteFile(handle, s.data, (u32)s.count, (LPDWORD)&written, nullptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void default_logger_proc (string log_message, Log_Level level, void* data) {
|
||||||
|
bool to_standard_error = level == Log_Level::Error || level == Log_Level::Fatal_Error;
|
||||||
|
|
||||||
|
lock(default_logger.mutex);
|
||||||
|
os_write_string_unsynchronized(log_message, to_standard_error);
|
||||||
|
unlock(default_logger.mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void default_logger_initialize() {
|
||||||
|
// see: Bootstrap_Main_Thread_Context
|
||||||
|
default_logger.mutex = New<Mutex>(true);
|
||||||
|
mutex_init(default_logger.mutex);
|
||||||
|
|
||||||
|
#if OS_WINDOWS
|
||||||
|
default_logger.windows_standard_output = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
default_logger.windows_standard_error = GetStdHandle(STD_ERROR_HANDLE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// more hacky forward declares
|
||||||
|
Logger* get_context_logger ();
|
||||||
|
Allocator get_temp_allocator ();
|
||||||
|
Allocator get_context_allocator ();
|
||||||
|
|
||||||
|
void log (string fmt, ...);
|
||||||
|
void print (string message);
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
#include "String.h"
|
|
||||||
|
|
||||||
// #TODO #string module
|
// #TODO #string module
|
||||||
// [ ] I'm debating if string type should automatically null-terminate.
|
// [ ] I'm debating if string type should automatically null-terminate.
|
||||||
// I personally do not like it, and think we should temp-copy c-strings as they're needed.
|
// I personally do not like it, and think we should temp-copy c-strings as they're needed.
|
||||||
@ -55,7 +53,7 @@ string to_string (ArrayView<u8> str) {
|
|||||||
return {str.count, str.data};
|
return {str.count, str.data};
|
||||||
}
|
}
|
||||||
|
|
||||||
void free (string& s) {
|
void string_free (string& s) {
|
||||||
internal_free(s.data);
|
internal_free(s.data);
|
||||||
|
|
||||||
s.data = nullptr;
|
s.data = nullptr;
|
||||||
@ -160,6 +158,21 @@ force_inline void append_no_add (String_Builder* sb, string s) {
|
|||||||
|
|
||||||
// Unfortunately this follows the printf format, which is annoying.
|
// Unfortunately this follows the printf format, which is annoying.
|
||||||
// I'd rather have something like fmt::
|
// I'd rather have something like fmt::
|
||||||
|
void print_to_builder (String_Builder* sb, string format, va_list args) {
|
||||||
|
s64 expected_final_count = sb->count + format.count + 4096;
|
||||||
|
|
||||||
|
if (sb->allocated < expected_final_count) {
|
||||||
|
array_reserve(*sb, expected_final_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 buffer_size = sb->allocated - sb->count; // available space
|
||||||
|
u8* current_point = &sb->data[sb->count];
|
||||||
|
|
||||||
|
s64 print_count = (s64)vsnprintf((char*)current_point, (size_t)buffer_size, (char*)format.data, args);
|
||||||
|
|
||||||
|
sb->count += print_count;
|
||||||
|
}
|
||||||
|
|
||||||
void print_to_builder (String_Builder* sb, string format, ...) {
|
void print_to_builder (String_Builder* sb, string format, ...) {
|
||||||
s64 expected_final_count = sb->count + format.count + 4096;
|
s64 expected_final_count = sb->count + format.count + 4096;
|
||||||
|
|
||||||
@ -185,7 +198,7 @@ string string_view (String_Builder* sb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// for when we want to keep the string builder around and recycle the memory.
|
// for when we want to keep the string builder around and recycle the memory.
|
||||||
internal force_inline void reset (String_Builder* sb) {
|
internal force_inline void reset_string_builder (String_Builder* sb) {
|
||||||
poison_range(*sb, 0, sb->count);
|
poison_range(*sb, 0, sb->count);
|
||||||
reset_keeping_memory(*sb);
|
reset_keeping_memory(*sb);
|
||||||
}
|
}
|
||||||
@ -193,11 +206,11 @@ internal force_inline void reset (String_Builder* sb) {
|
|||||||
force_inline string builder_to_string (String_Builder* sb) {
|
force_inline string builder_to_string (String_Builder* sb) {
|
||||||
string final_string = copy_string(to_string(to_view(*sb)));
|
string final_string = copy_string(to_string(to_view(*sb)));
|
||||||
|
|
||||||
free(sb);
|
free_string_builder(sb);
|
||||||
|
|
||||||
return final_string;
|
return final_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal force_inline void free (String_Builder* sb) {
|
internal force_inline void free_string_builder (String_Builder* sb) {
|
||||||
arena_array_free(*sb);
|
arena_array_free(*sb);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
// #TODO: #strings:
|
// #TODO: #strings:
|
||||||
// [ ] Always null-terminate strings!
|
// [ ] Always null-terminate strings!
|
||||||
// [ ] How do I accept variadic arguments of any type to my print function?
|
// [ ] How do I accept variadic arguments of any type to my print function?
|
||||||
@ -92,9 +93,10 @@ force_inline void append (String_Builder* sb, string s);
|
|||||||
void append (String_Builder* sb, ArrayView<string> strings);
|
void append (String_Builder* sb, ArrayView<string> strings);
|
||||||
internal force_inline void append_no_add (String_Builder* sb, string s); // for appending null terminators, does not increment count.
|
internal force_inline void append_no_add (String_Builder* sb, string s); // for appending null terminators, does not increment count.
|
||||||
void print_to_builder (String_Builder* sb, string format, ...);
|
void print_to_builder (String_Builder* sb, string format, ...);
|
||||||
|
void print_to_builder (String_Builder* sb, string format, va_list args);
|
||||||
string string_view (String_Builder* sb);
|
string string_view (String_Builder* sb);
|
||||||
internal force_inline void reset (String_Builder* sb);
|
internal force_inline void reset_string_builder (String_Builder* sb);
|
||||||
|
|
||||||
force_inline string builder_to_string (String_Builder* sb); // returns string view
|
force_inline string builder_to_string (String_Builder* sb); // returns string view
|
||||||
internal force_inline void free (String_Builder* sb);
|
internal force_inline void free_string_builder (String_Builder* sb);
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,10 @@
|
|||||||
|
|
||||||
#include "lib/Base/Arena.h"
|
#include "lib/Base/Arena.h"
|
||||||
#include "lib/Base/Arena_Array.h"
|
#include "lib/Base/Arena_Array.h"
|
||||||
|
#include "lib/Base/String.h"
|
||||||
|
#include "lib/Base/Logger.h"
|
||||||
#include "lib/Base/String.cpp"
|
#include "lib/Base/String.cpp"
|
||||||
|
|
||||||
#include "lib/Base/ErrorType.cpp"
|
#include "lib/Base/ErrorType.cpp"
|
||||||
#include "lib/Base/Arena_Table.cpp"
|
#include "lib/Base/Arena_Table.cpp"
|
||||||
#include "lib/Base/Base_Thread_Context.h"
|
#include "lib/Base/Base_Thread_Context.h"
|
||||||
@ -27,6 +30,7 @@
|
|||||||
#include "lib/Base/Arena.cpp"
|
#include "lib/Base/Arena.cpp"
|
||||||
|
|
||||||
#include "lib/Base/Base_Thread_Context.cpp"
|
#include "lib/Base/Base_Thread_Context.cpp"
|
||||||
|
#include "lib/Base/Logger.cpp"
|
||||||
#include "lib/Base/Expandable_Arena.cpp"
|
#include "lib/Base/Expandable_Arena.cpp"
|
||||||
#include "lib/Base/Allocator.cpp"
|
#include "lib/Base/Allocator.cpp"
|
||||||
#include "lib/Base/General_Purpose_Allocator.cpp"
|
#include "lib/Base/General_Purpose_Allocator.cpp"
|
||||||
|
|||||||
@ -189,13 +189,14 @@ string string_literal_example = "Hello, I am a string literal.";
|
|||||||
|
|
||||||
internal void Main_Entry_Point (int argc, WCHAR **argv) {
|
internal void Main_Entry_Point (int argc, WCHAR **argv) {
|
||||||
temp_reset();
|
temp_reset();
|
||||||
|
push_allocator(get_temp_allocator());
|
||||||
// tip: use auto_reset or auto_release with `get_thread_context()->arena`
|
// tip: use auto_reset or auto_release with `get_thread_context()->arena`
|
||||||
|
|
||||||
debug_break();
|
// debug_break();
|
||||||
|
|
||||||
// String builder example:
|
// String builder example:
|
||||||
// OK. I can work with this.
|
// OK. I can work with this.
|
||||||
/*
|
|
||||||
auto sb = new_string_builder(Arena_Reserve::Size_64K);
|
auto sb = new_string_builder(Arena_Reserve::Size_64K);
|
||||||
append(sb, "string_literal_example");
|
append(sb, "string_literal_example");
|
||||||
append(sb, " ");
|
append(sb, " ");
|
||||||
@ -203,18 +204,23 @@ internal void Main_Entry_Point (int argc, WCHAR **argv) {
|
|||||||
append(sb, " > ");
|
append(sb, " > ");
|
||||||
print_to_builder(sb, "some size_t: %u", (u64)3982739867);
|
print_to_builder(sb, "some size_t: %u", (u64)3982739867);
|
||||||
append(sb, "\n");
|
append(sb, "\n");
|
||||||
|
print_to_builder(sb, "the literal: %s", string_literal_example.data);
|
||||||
|
|
||||||
// auto result = string_view(sb);
|
// string result = string_view(sb);
|
||||||
auto result = builder_to_string(sb);
|
auto result = builder_to_string(sb); // also frees
|
||||||
printf((char*)result.data);
|
// print((char*)result.data);
|
||||||
|
log("Hello.");
|
||||||
|
log("log() should automatically append newlines to these prints.");
|
||||||
|
log("If it doesn't, I will be very upset.");
|
||||||
|
log(result);
|
||||||
|
log("Hello. There are %s things here\n", string_literal_example.data);
|
||||||
|
|
||||||
auto array = array_from_values<s32>(6,7,8,9,10,51);
|
print("Hello, I am just a printed message to stdout");
|
||||||
auto view = array_view_from_values<s32>(1,2,3,4,5);
|
|
||||||
*/
|
// free_string_builder(sb);
|
||||||
|
|
||||||
// ImGui_Application();
|
// ImGui_Application();
|
||||||
|
|
||||||
|
|
||||||
// #TODO: #Main - `Main_Entry_Point`
|
// #TODO: #Main - `Main_Entry_Point`
|
||||||
// [ ] Setup Mouse and Keyboard Inputs
|
// [ ] Setup Mouse and Keyboard Inputs
|
||||||
// [ ] Launch second thread
|
// [ ] Launch second thread
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user