Setup Context's logger and fallback. (Not yet used in implementation).

This commit is contained in:
Edward R. Gonzalez 2025-02-19 10:50:36 -05:00
parent 727b54c341
commit 844d431e1c
7 changed files with 95 additions and 46 deletions

View File

@ -71,6 +71,14 @@ void* fallback_allocator_proc( void* allocator_data, AllocType type, ssize size,
return nullptr; return nullptr;
} }
internal
void fallback_logger(LogEntry entry)
{
GEN_ASSERT(entry.msg.Len > 0);
GEN_ASSERT(entry.msg.Ptr);
log_fmt("%S: %S", loglevel_to_str(entry.level), entry.msg);
}
internal internal
void define_constants() void define_constants()
{ {
@ -292,6 +300,10 @@ void init(Context* ctx)
ctx->InitSize_MacrosTable = kilobytes(8); ctx->InitSize_MacrosTable = kilobytes(8);
} }
if (ctx->Logger == nullptr) {
ctx->Logger = & fallback_logger;
}
// Override the current context (user has to put it back if unwanted). // Override the current context (user has to put it back if unwanted).
_ctx = ctx; _ctx = ctx;
@ -307,7 +319,7 @@ void init(Context* ctx)
} }
// Setup the code pool and code entries arena. // Setup the code pool and code entries arena.
{ {
Pool code_pool = pool_init( ctx->Allocator_Pool, ctx->CodePool_NumBlocks, sizeof(AST) ); Pool code_pool = pool_init( ctx->Allocator_Pool, ctx->CodePool_NumBlocks, size_of(AST) );
if ( code_pool.PhysicalStart == nullptr ) if ( code_pool.PhysicalStart == nullptr )
GEN_FATAL( "gen::init: Failed to initialize the code pool" ); GEN_FATAL( "gen::init: Failed to initialize the code pool" );
array_append( ctx->CodePools, code_pool ); array_append( ctx->CodePools, code_pool );

View File

@ -15,23 +15,34 @@
\ \\ \ \\ \ \ \\ \ \ \ \ \ \\ \ \\ \ \ \\ \ \ \ \
*/ */
#if 0
enum LogLevel : u32 enum LogLevel : u32
{ {
Info, LL_Null,
Warning, LL_Note,
Panic, LL_Warning,
LL_Error,
LL_Fatal,
LL_UnderlyingType = GEN_U32_MAX,
}; };
Str loglevel_to_str(LogLevel level)
{
local_persist
Str lookup[] = {
txt("Info"),
txt("Warning"),
txt("Panic"),
};
return lookup[level];
}
struct LogEntry struct LogEntry
{ {
Str msg; Str msg;
u32 line_num; LogLevel level;
void* data;
}; };
typedef void LoggerCallback(LogEntry entry); typedef void LoggerProc(LogEntry entry);
#endif
// Note(Ed): This is subject to heavily change // Note(Ed): This is subject to heavily change
// with upcoming changes to the library's fallback (default) allocations strategy; // with upcoming changes to the library's fallback (default) allocations strategy;
@ -70,6 +81,10 @@ struct Context
// TODO(Ed): Symbol Table // TODO(Ed): Symbol Table
// Keep track of all resolved symbols (naemspaced identifiers) // Keep track of all resolved symbols (naemspaced identifiers)
// Logging
LoggerProc* Logger;
// Parser // Parser
// Used by the lexer to persistently treat all these identifiers as preprocessor defines. // Used by the lexer to persistently treat all these identifiers as preprocessor defines.
@ -107,6 +122,45 @@ struct Context
// An implicit context interface will be provided instead as wrapper procedures as convience. // An implicit context interface will be provided instead as wrapper procedures as convience.
GEN_API extern Context* _ctx; GEN_API extern Context* _ctx;
// By default this library will either crash or exit if an error is detected while generating codes.
// Even if set to not use GEN_FATAL, GEN_FATAL will still be used for memory failures as the library is unusable when they occur.
#ifdef GEN_DONT_USE_FATAL
#define log_failure log_fmt
#else
#define log_failure GEN_FATAL
#endif
// TODO(Ed): Swap all usage of this with logger_fmt (then rename logger_fmt to log_fmt)
inline
ssize log_fmt(char const* fmt, ...)
{
ssize res;
va_list va;
va_start(va, fmt);
res = c_str_fmt_out_va(fmt, va);
va_end(va);
return res;
}
inline
void logger_fmt(Context* ctx, LogLevel level, char const* fmt, ...)
{
local_persist thread_local
PrintF_Buffer buf = struct_init(PrintF_Buffer, {0});
va_list va;
va_start(va, fmt);
ssize res = c_str_fmt_va(buf, GEN_PRINTF_MAXLEN, fmt, va) -1;
va_end(va);
StrBuilder msg = strbuilder_make_length(ctx->Allocator_Temp, buf, res);
LogEntry entry = { strbuilder_to_str(msg), level };
ctx->Logger(entry);
}
// Initialize the library. There first ctx initialized must exist for lifetime of other contextes that come after as its the one that // Initialize the library. There first ctx initialized must exist for lifetime of other contextes that come after as its the one that
GEN_API void init(Context* ctx); GEN_API void init(Context* ctx);
@ -117,7 +171,7 @@ GEN_API void deinit(Context* ctx);
// Retrieves the active context (not usually needed, but here in case...) // Retrieves the active context (not usually needed, but here in case...)
GEN_API Context* get_context(); GEN_API Context* get_context();
// Clears the allocations, but doesn't free the memoery, then calls init() again. // Clears the allocations, but doesn't free the memory, then calls init() again.
// Ease of use. // Ease of use.
GEN_API void reset(Context* ctx); GEN_API void reset(Context* ctx);
@ -398,7 +452,7 @@ GEN_API ssize token_fmt_va( char* buf, usize buf_size, s32 num_tokens, va_list v
//! Do not use directly. Use the token_fmt macro instead. //! Do not use directly. Use the token_fmt macro instead.
Str token_fmt_impl( ssize, ... ); Str token_fmt_impl( ssize, ... );
GEN_API Code untyped_str( Str content); GEN_API Code untyped_str ( Str content);
GEN_API Code untyped_fmt ( char const* fmt, ... ); GEN_API Code untyped_fmt ( char const* fmt, ... );
GEN_API Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... ); GEN_API Code untyped_token_fmt( s32 num_tokens, char const* fmt, ... );

View File

@ -19,16 +19,6 @@
*/ */
using LogFailType = ssize(*)(char const*, ...);
// By default this library will either crash or exit if an error is detected while generating codes.
// Even if set to not use GEN_FATAL, GEN_FATAL will still be used for memory failures as the library is unusable when they occur.
#ifdef GEN_DONT_USE_FATAL
#define log_failure log_fmt
#else
#define log_failure GEN_FATAL
#endif
enum AccessSpec : u32 enum AccessSpec : u32
{ {
AccessSpec_Default, AccessSpec_Default,

View File

@ -187,7 +187,7 @@ struct FileContents
{ {
AllocatorInfo allocator; AllocatorInfo allocator;
void* data; void* data;
ssize size; ssize size;
}; };
constexpr b32 file_zero_terminate = true; constexpr b32 file_zero_terminate = true;

View File

@ -298,10 +298,20 @@
# define GEN_PARAM_DEFAULT # define GEN_PARAM_DEFAULT
#endif #endif
#if GEN_COMPILER_CPP #ifndef struct_init
#define struct_init(type, value) {value} # if GEN_COMPILER_CPP
#else # define struct_init(type, value) value
#define struct_init(type, value) {value} # else
# define struct_init(type, value) (type) value
# endif
#endif
#ifndef struct_zero
# if GEN_COMPILER_CPP
# define struct_zero(type) {}
# else
# define struct_zero(type) (type) {0}
# endif
#endif #endif
#if 0 #if 0

View File

@ -134,12 +134,6 @@ GEN_API void* heap_allocator_proc( void* allocator_data, AllocType type, ssize s
//! The heap allocator backed by operating system's memory manager. //! The heap allocator backed by operating system's memory manager.
constexpr AllocatorInfo heap( void ) { AllocatorInfo allocator = { heap_allocator_proc, nullptr }; return allocator; } constexpr AllocatorInfo heap( void ) { AllocatorInfo allocator = { heap_allocator_proc, nullptr }; return allocator; }
//! Helper to allocate memory using heap allocator.
#define malloc( sz ) alloc( heap(), sz )
//! Helper to free memory allocated by heap allocator.
#define mfree( ptr ) allocator_free( heap(), ptr )
struct VirtualMemory struct VirtualMemory
{ {
void* data; void* data;
@ -185,6 +179,8 @@ void arena_check (Arena* arena);
void arena_free (Arena* arena); void arena_free (Arena* arena);
ssize arena_size_remaining(Arena* arena, ssize alignment); ssize arena_size_remaining(Arena* arena, ssize alignment);
// TODO(Ed): Add arena_pos, arena_pop, and arena_pop_to
struct Arena struct Arena
{ {
AllocatorInfo Backing; AllocatorInfo Backing;

View File

@ -26,17 +26,4 @@ GEN_API ssize c_str_fmt_file_va ( FileInfo* f, char const* fmt, va_list va );
constexpr constexpr
char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED"; char const* Msg_Invalid_Value = "INVALID VALUE PROVIDED";
inline
ssize log_fmt(char const* fmt, ...)
{
ssize res;
va_list va;
va_start(va, fmt);
res = c_str_fmt_out_va(fmt, va);
va_end(va);
return res;
}
#pragma endregion Printing #pragma endregion Printing