#pragma once #include "Base.h" enum ErrorSeverity: s32 { SEVERITY_WARNING = 0, SEVERITY_NON_FATAL = 1, SEVERITY_FATAL = 2 }; #include "Base_String.h" // typedef struct string Native_Error; // Note: Native_Error should down-cast to a string. struct Native_Error { s64 count; u8* data; ErrorSeverity severity = SEVERITY_WARNING; }; #define Null_Pointer_Check(arg) \ if (arg == nullptr) { \ return New_Fatal_Error_Internal("%s:%d\n[%s] Error: %s is a null pointer.", __FILE__, __LINE__, __FUNCTION__, Stringify(arg)); \ } #define Array_Check(arg) \ if (!is_valid(arg)) { \ return New_Fatal_Error_Internal("%s:%d\n[%s] Error: %s is not a valid array.", __FILE__, __LINE__, __FUNCTION__, Stringify(arg)); \ } #define String_Check(arg) \ if (!Is_Valid(arg)) { return New_Fatal_Error_Internal("%s:%d\n[%s] Error: %s is not a valid string.", __FILE__, __LINE__, __FUNCTION__, Stringify(arg)); } #define Error_Check(error) \ if (error != nullptr) { \ return error; \ } // An error from which the program cannot continue (e.g. a segmentation fault) #define New_Fatal_Error(message) \ New_Fatal_Error_Internal("%s:%d\n[%s] Error: %s.", __FILE__, __LINE__, __FUNCTION__, message) #define New_Error(message) \ New_Error_Internal("%s:%d\n[%s] Error: %s.", __FILE__, __LINE__, __FUNCTION__, message) #define New_Warning(message) \ New_Warning_Internal("%s:%d\n[%s] Warning: %s.", __FILE__, __LINE__, __FUNCTION__, message) Native_Error* New_Fatal_Error_Internal(char* raw_message, ...); Native_Error* New_Error_Internal(char* raw_message, ...); Native_Error* New_Warning_Internal(char* raw_message, ...); Native_Error* Native_Error_Callstack(Native_Error* new_error, Native_Error* old_error, ErrorSeverity severity); PROTOTYPING_API C_API Native_Error* Cleanup_Error(Native_Error* error); PROTOTYPING_API C_API Native_Error* Native_Error_Test();