138 lines
3.9 KiB
C
138 lines
3.9 KiB
C
/*************************************************************************
|
|
*
|
|
* Orca
|
|
* Copyright 2023 Martin Fouilleul and the Orca project contributors
|
|
* See LICENSE.txt for licensing information
|
|
*
|
|
**************************************************************************/
|
|
#include <stdarg.h>
|
|
|
|
#include "platform_debug.c"
|
|
#include "util/strings.h"
|
|
|
|
//----------------------------------------------------------------
|
|
// stb sprintf callback and user struct
|
|
//----------------------------------------------------------------
|
|
|
|
typedef struct oc_stbsp_context
|
|
{
|
|
oc_arena* arena;
|
|
oc_str8_list list;
|
|
} oc_stbsp_context;
|
|
|
|
char* oc_stbsp_callback(char const* buf, void* user, int len)
|
|
{
|
|
oc_stbsp_context* ctx = (oc_stbsp_context*)user;
|
|
|
|
oc_str8 string = oc_str8_push_buffer(ctx->arena, len, (char*)buf);
|
|
oc_str8_list_push(ctx->arena, &ctx->list, string);
|
|
|
|
return ((char*)buf);
|
|
}
|
|
|
|
//----------------------------------------------------------------
|
|
// Logging
|
|
//----------------------------------------------------------------
|
|
|
|
typedef enum
|
|
{
|
|
ORCA_LOG_OUTPUT_CONSOLE,
|
|
ORCA_LOG_OUTPUT_FILE
|
|
} oc_log_output_kind;
|
|
|
|
typedef struct oc_log_output
|
|
{
|
|
oc_log_output_kind kind;
|
|
//TODO: file output
|
|
} oc_log_output;
|
|
|
|
static oc_log_output oc_logDefaultOutput = { .kind = ORCA_LOG_OUTPUT_CONSOLE };
|
|
oc_log_output* OC_LOG_DEFAULT_OUTPUT = &oc_logDefaultOutput;
|
|
|
|
void ORCA_IMPORT(oc_bridge_log)(oc_log_level level,
|
|
int fileLen,
|
|
const char* file,
|
|
int functionLen,
|
|
const char* function,
|
|
int line,
|
|
int msgLen,
|
|
const char* msg);
|
|
|
|
void platform_log_push(oc_log_output* output,
|
|
oc_log_level level,
|
|
const char* file,
|
|
const char* function,
|
|
int line,
|
|
const char* fmt,
|
|
va_list ap)
|
|
{
|
|
oc_arena_scope scratch = oc_scratch_begin();
|
|
|
|
oc_stbsp_context ctx = { .arena = scratch.arena,
|
|
.list = { 0 } };
|
|
|
|
char buf[STB_SPRINTF_MIN];
|
|
stbsp_vsprintfcb(oc_stbsp_callback, &ctx, buf, fmt, ap);
|
|
|
|
oc_str8 string = oc_str8_list_join(scratch.arena, ctx.list);
|
|
|
|
oc_bridge_log(level, strlen(file), file, strlen(function), function, line, oc_str8_ip(string));
|
|
|
|
oc_scratch_end(scratch);
|
|
}
|
|
|
|
//----------------------------------------------------------------
|
|
// Assert/Abort
|
|
//----------------------------------------------------------------
|
|
|
|
_Noreturn void ORCA_IMPORT(oc_bridge_abort_ext)(const char* file, const char* function, int line, const char* msg);
|
|
_Noreturn void ORCA_IMPORT(oc_bridge_assert_fail)(const char* file, const char* function, int line, const char* src, const char* msg);
|
|
|
|
_Noreturn void oc_abort_ext(const char* file, const char* function, int line, const char* fmt, ...)
|
|
{
|
|
oc_arena_scope scratch = oc_scratch_begin();
|
|
|
|
oc_stbsp_context ctx = {
|
|
.arena = scratch.arena,
|
|
.list = { 0 }
|
|
};
|
|
|
|
va_list ap;
|
|
va_start(ap, fmt);
|
|
|
|
char buf[STB_SPRINTF_MIN];
|
|
stbsp_vsprintfcb(oc_stbsp_callback, &ctx, buf, fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
oc_str8 msg = oc_str8_list_join(scratch.arena, ctx.list);
|
|
|
|
oc_bridge_abort_ext(file, function, line, msg.ptr);
|
|
|
|
oc_scratch_end(scratch);
|
|
}
|
|
|
|
_Noreturn void oc_assert_fail(const char* file, const char* function, int line, const char* src, const char* fmt, ...)
|
|
{
|
|
oc_arena_scope scratch = oc_scratch_begin();
|
|
|
|
oc_stbsp_context ctx = {
|
|
.arena = scratch.arena,
|
|
.list = { 0 }
|
|
};
|
|
|
|
va_list ap;
|
|
va_start(ap, fmt);
|
|
|
|
char buf[STB_SPRINTF_MIN];
|
|
stbsp_vsprintfcb(oc_stbsp_callback, &ctx, buf, fmt, ap);
|
|
|
|
va_end(ap);
|
|
|
|
oc_str8 msg = oc_str8_list_join(scratch.arena, ctx.list);
|
|
|
|
oc_bridge_assert_fail(file, function, line, src, msg.ptr);
|
|
|
|
oc_scratch_end(scratch);
|
|
}
|