110 lines
3.0 KiB
C++
110 lines
3.0 KiB
C++
#include "error-codes.h"
|
|
|
|
#include "General_Purpose_Allocator.h"
|
|
#include <stdio.h> // vsnprintf, printf
|
|
#include <cstdarg> // va_list...
|
|
|
|
// Should always be false when making python bindings.
|
|
#define BREAK_ON_WARNINGS 0
|
|
#define BREAK_ON_ERRORS 0
|
|
#define BREAK_ON_FATAL_ERROR BUILD_DEBUG
|
|
#define ALWAYS_PRINT_ERROR_MESSAGES BUILD_DEBUG
|
|
|
|
Native_Error* Create_New_Native_Error_Internal(char* format, va_list args) {
|
|
constexpr s64 ERROR_BUFFER_COUNT = 512;
|
|
|
|
auto error = ALLOCATE(Native_Error);
|
|
error->data = ALLOCATE_RAW_ARRAY(ERROR_BUFFER_COUNT, u8);
|
|
|
|
// You MUST copy the va_list before using it more than once
|
|
va_list args_copy;
|
|
va_copy(args_copy, args);
|
|
error->count = (s64)vsnprintf((char*)error->data, (size_t)ERROR_BUFFER_COUNT, format, args_copy);
|
|
va_end(args_copy);
|
|
|
|
return error;
|
|
}
|
|
|
|
Native_Error* New_Fatal_Error_Internal(char* format, ...) {
|
|
va_list args;
|
|
va_start(args, format);
|
|
auto error = Create_New_Native_Error_Internal(format, args);
|
|
va_end(args);
|
|
|
|
error->severity = SEVERITY_FATAL;
|
|
#if BUILD_DEBUG && ALWAYS_PRINT_ERROR_MESSAGES
|
|
printf("[FATAL ERROR] %.*s\n", (s32)error->count, (char*)error->data);
|
|
#endif
|
|
#if BREAK_ON_FATAL_ERROR
|
|
debug_break();
|
|
#endif
|
|
|
|
return error;
|
|
}
|
|
|
|
Native_Error* Native_Error_Callstack(Native_Error* new_error, Native_Error* old_error, ErrorSeverity severity) {
|
|
auto error_message = format_string("%s\n > %s", new_error->data, old_error->data).data;
|
|
|
|
Cleanup_Error(new_error);
|
|
Cleanup_Error(old_error);
|
|
|
|
Native_Error* error_merged = ALLOCATE(Native_Error);
|
|
error_merged->data = (u8*)error_message;
|
|
error_merged->count = strlen((char*)error_merged->data);
|
|
error_merged->severity = severity;
|
|
|
|
return error_merged;
|
|
}
|
|
|
|
Native_Error* Native_Error_Test() {
|
|
// This is quite verbose, but w/e
|
|
auto old_error = New_Error("Original error...");
|
|
auto new_message = format_string("Failed to start stream. Error Code: %d", -1).data;
|
|
auto new_error = New_Error(new_message);
|
|
GPAllocator_Delete(new_message);
|
|
|
|
return Native_Error_Callstack(new_error, old_error, SEVERITY_NON_FATAL);
|
|
}
|
|
|
|
Native_Error* New_Error_Internal(char* format, ...) {
|
|
va_list args;
|
|
va_start(args, format);
|
|
auto error = Create_New_Native_Error_Internal(format, args);
|
|
va_end(args);
|
|
|
|
error->severity = SEVERITY_NON_FATAL;
|
|
#if BUILD_DEBUG && ALWAYS_PRINT_ERROR_MESSAGES
|
|
printf("[ERROR (NON-FATAL)] %.*s\n", (s32)error->count, (char*)error->data);
|
|
#endif
|
|
#if BREAK_ON_ERRORS
|
|
debug_break();
|
|
#endif
|
|
|
|
return error;
|
|
}
|
|
|
|
Native_Error* New_Warning_Internal(char* format, ...) {
|
|
va_list args;
|
|
va_start(args, format);
|
|
auto error = Create_New_Native_Error_Internal(format, args);
|
|
va_end(args);
|
|
|
|
error->severity = SEVERITY_WARNING;
|
|
#if BUILD_DEBUG && ALWAYS_PRINT_ERROR_MESSAGES
|
|
printf("[WARNING] %.*s\n", (s32)error->count, (char*)error->data);
|
|
#endif
|
|
#if BREAK_ON_WARNINGS
|
|
debug_break();
|
|
#endif
|
|
|
|
return error;
|
|
}
|
|
|
|
Native_Error* Cleanup_Error(Native_Error* error) {
|
|
if (error == nullptr) return nullptr;
|
|
|
|
GPAllocator_Delete(error->data);
|
|
GPAllocator_Delete(error);
|
|
|
|
return nullptr;
|
|
} |