/************************************************************/ /** * * @file: native_debug.c * @author: Martin Fouilleul * @date: 13/08/2023 * *****************************************************************/ #include #include "app/app.h" #include "platform_debug.c" //---------------------------------------------------------------- // Logging //---------------------------------------------------------------- #if OC_PLATFORM_WINDOWS #include #define isatty _isatty #define fileno _fileno #elif OC_PLATFORM_MACOS || PLATFORM_LINUX #include #endif static const char* OC_LOG_HEADINGS[OC_LOG_LEVEL_COUNT] = { "Error", "Warning", "Info" }; static const char* OC_LOG_FORMATS[OC_LOG_LEVEL_COUNT] = { "\033[38;5;9m\033[1m", "\033[38;5;13m\033[1m", "\033[38;5;10m\033[1m" }; static const char* OC_LOG_FORMAT_STOP = "\033[m"; typedef struct oc_log_output { FILE* f; } oc_log_output; static oc_log_output oc_logDefaultOutput = { 0 }; oc_log_output* OC_LOG_DEFAULT_OUTPUT = &oc_logDefaultOutput; 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) { if(output == OC_LOG_DEFAULT_OUTPUT && output->f == 0) { output->f = stdout; } int fd = fileno(output->f); if(isatty(fd)) { fprintf(output->f, "%s%s:%s %s() in %s:%i: ", OC_LOG_FORMATS[level], OC_LOG_HEADINGS[level], OC_LOG_FORMAT_STOP, function, file, line); } else { fprintf(output->f, "%s: %s() in %s:%i: ", OC_LOG_HEADINGS[level], function, file, line); } vfprintf(output->f, fmt, ap); } //---------------------------------------------------------------- // Assert/Abort //---------------------------------------------------------------- _Noreturn void oc_abort_ext(const char* file, const char* function, int line, const char* fmt, ...) { oc_arena* scratch = oc_scratch(); va_list ap; va_start(ap, fmt); oc_str8 note = oc_str8_pushfv(scratch, fmt, ap); va_end(ap); oc_str8 msg = oc_str8_pushf(scratch, "Fatal error in function %s() in file \"%s\", line %i:\n%.*s\n", function, file, line, (int)note.len, note.ptr); oc_log_error(msg.ptr); oc_str8_list options = { 0 }; oc_str8_list_push(scratch, &options, OC_STR8("OK")); oc_alert_popup(OC_STR8("Fatal Error"), msg, options); //TODO: could terminate more gracefully? exit(-1); } _Noreturn void oc_assert_fail(const char* file, const char* function, int line, const char* src, const char* fmt, ...) { oc_arena* scratch = oc_scratch(); va_list ap; va_start(ap, fmt); oc_str8 note = oc_str8_pushfv(scratch, fmt, ap); va_end(ap); oc_str8 msg = oc_str8_pushf(scratch, "Assertion failed in function %s() in file \"%s\", line %i:\n%s\nNote: %.*s\n", function, file, line, src, oc_str8_ip(note)); oc_log_error(msg.ptr); oc_str8_list options = { 0 }; oc_str8_list_push(scratch, &options, OC_STR8("OK")); oc_alert_popup(OC_STR8("Assertion Failed"), msg, options); //TODO: could terminate more gracefully? exit(-1); }