/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: SysErrors.hpp Date: 2021-6-10 Author: Reece ***/ #pragma once namespace Aurora::Debug { AUKN_SYM void _PushError(AuUInt address, EFailureCategory category, const char *msg); #if defined(AURORA_COMPILER_MSVC) #define _DBG_RET_ADDR (AuUInt)_ReturnAddress() #elif defined(AURORA_COMPILER_CLANG) #define _DBG_RET_ADDR (AuUInt)__builtin_return_address(0) #else #define _DBG_RET_ADDR AuUInt(0) #endif #if defined(AURORA_COMPILER_MSVC) #pragma optimize("", off) #define _FREECOMPILER_OPTIMIZE_OFF #elif defined(AURORA_COMPILER_CLANG) #define _FREECOMPILER_OPTIMIZE_OFF __attribute__((optnone)) #else #define _FREECOMPILER_OPTIMIZE_OFF __attribute__((optimize("0"))) #endif // TODO: bring the xenus thing into here static AU_NOINLINE AuUInt GetIPNoBackend() _FREECOMPILER_OPTIMIZE_OFF { return _DBG_RET_ADDR; } #if defined(AURORA_COMPILER_MSVC) #pragma optimize("", on) #endif #undef _FREECOMPILER_OPTIMIZE_OFF static auline void ErrorMakeNested() { _PushError(_DBG_RET_ADDR, EFailureCategory::kFailureNested, nullptr); } template auline void ErrorMakeNested(const AuString &msg, T&& ... args) { if constexpr (sizeof...(T) == 0) { _PushError(_DBG_RET_ADDR, EFailureCategory::kFailureNested, msg.c_str()); } else { #if defined(_AUHAS_FMT) try { auto tempString = fmt::format(msg, AuForward(args)...); _PushError(_DBG_RET_ADDR, EFailureCategory::kFailureNested, tempString.c_str()); } catch (...) { _PushError(_DBG_RET_ADDR, EFailureCategory::kFailureNested, msg.c_str()); } #else _PushError(_DBG_RET_ADDR, EFailureCategory::kFailureNested, msg.c_str()); #endif } } static auline void ErrorMakeNested(const char *msg) { _PushError(_DBG_RET_ADDR, EFailureCategory::kFailureNested, msg); } template auline void SysPushError(EFailureCategory category, const AuString &msg, T&& ... args) { if constexpr (sizeof...(T) == 0) { _PushError(_DBG_RET_ADDR, category, msg.c_str()); } else { #if defined(_AUHAS_FMT) try { auto tempString = fmt::format(msg, AuForward(args)...); _PushError(_DBG_RET_ADDR, category, tempString.c_str()); } catch (...) { _PushError(_DBG_RET_ADDR, category, msg.c_str()); } #else _PushError(_DBG_RET_ADDR, category, msg.c_str()); #endif } } static auline void SysPushError(EFailureCategory category, const char *msg) { _PushError(_DBG_RET_ADDR, category, msg); } static auline void SysPushError(EFailureCategory category) { _PushError(_DBG_RET_ADDR, category, nullptr); } } #define SysCheckReturn(x, ...) if (!(static_cast(x))) { Aurora::Debug::ErrorMakeNested(); return __VA_ARGS__; } #define SysPushErrorError(error, ...) Aurora::Debug::SysPushError(Aurora::Debug::error, ## __VA_ARGS__) #define SysPushUserError(exp, ...) Aurora::Debug::SysPushError((Aurora::Debug::EFailureCategory)exp, ## __VA_ARGS__) // legacy #define SysPushErrorArg(...) SysPushErrorError(kFailureParam, ## __VA_ARGS__) #define SysPushErrorGen(...) SysPushErrorError(kFailureGeneric, ## __VA_ARGS__) #define SysPushErrorCrypt(...) SysPushErrorError(kFailureCrypto, ## __VA_ARGS__) #define SysPushErrorNet(...) SysPushErrorError(kFailureNet, ## __VA_ARGS__) #define SysPushErrorMem(...) SysPushErrorError(kFailureMemory, ## __VA_ARGS__) // edge case #define SysPushErrorNested(...) Aurora::Debug::ErrorMakeNested(__VA_ARGS__); // enums #define SysPushErrorGeneric(...) SysPushErrorError(kFailureGeneric, ## __VA_ARGS__) #define SysPushErrorCatch(...) SysPushErrorError(kFailureCatch, ## __VA_ARGS__) #define SysPushErrorMemory(...) SysPushErrorError(kFailureMemory, ## __VA_ARGS__) #define SysPushErrorIO(...) SysPushErrorError(kFailureIO, ## __VA_ARGS__) #define SysPushErrorFIO(...) SysPushErrorError(kFailureFIO, ## __VA_ARGS__) #define SysPushErrorNet(...) SysPushErrorError(kFailureNet, ## __VA_ARGS__) #define SysPushErrorAudio(...) SysPushErrorError(kFailureAudio, ## __VA_ARGS__) #define SysPushErrorHAL(...) SysPushErrorError(kFailureHAL, ## __VA_ARGS__) #define SysPushErrorHALContext(...) SysPushErrorError(kFailureHALContext, ## __VA_ARGS__) #define SysPushErrorCrypto(...) SysPushErrorError(kFailureCrypto, ## __VA_ARGS__) #define SysPushErrorParam(...) SysPushErrorError(kFailureParam, ## __VA_ARGS__) #define SysPushErrorLogicError(...) SysPushErrorError(kFailureLogicError, ## __VA_ARGS__) #define SysPushErrorMathError(...) SysPushErrorError(kFailureMathError, ## __VA_ARGS__) #define SysPushErrorUnavailableError(...) SysPushErrorError(kFailureUnavailableError, ## __VA_ARGS__) #define SysPushErrorTimeoutError(...) SysPushErrorError(kFailureTimeoutError, ## __VA_ARGS__) #define SysPushErrorWatchdogError(...) SysPushErrorError(kFailureWatchdogError, ## __VA_ARGS__) #define SysPushErrorServiceError(...) SysPushErrorError(kFailureServiceError, ## __VA_ARGS__) #define SysPushErrorPermissionError(...) SysPushErrorError(kFailurePermissionError, ## __VA_ARGS__) #define SysPushErrorOutOfRange(...) SysPushErrorError(kFailureOutOfRange, ## __VA_ARGS__) #define SysPushErrorSyntaxError(...) SysPushErrorError(kFailureSyntaxError, ## __VA_ARGS__) #define SysPushErrorDisconnected(...) SysPushErrorError(kFailureDisconnected, ## __VA_ARGS__) #define SysPushErrorUninitialized(...) SysPushErrorError(kFailureUninitialized, ## __VA_ARGS__) #define SysPushErrorUnimplemented(...) SysPushErrorError(kFailureUnimplemented, ## __VA_ARGS__) #define SysPushErrorSubmission(...) SysPushErrorError(kFailureSubmission, ## __VA_ARGS__) #define SysPushErrorLockError(...) SysPushErrorError(kFailureLockError, ## __VA_ARGS__) #define SysPushErrorSyntax(...) SysPushErrorError(kFailureSyntax, ## __VA_ARGS__) #define SysPushErrorNoAccess(...) SysPushErrorError(kFailureNoAccess, ## __VA_ARGS__) #define SysPushErrorResourceMissing(...) SysPushErrorError(kFailureResourceMissing, ## __VA_ARGS__) #define SysPushErrorResourceLocked(...) SysPushErrorError(kFailureResourceLocked, ## __VA_ARGS__) #define SysPushErrorMalformedData(...) SysPushErrorError(kFailureMalformedData, ## __VA_ARGS__) #define SysPushErrorInSandboxContext(...) SysPushErrorError(kFailureInSandboxContext, ## __VA_ARGS__) #define SysPushErrorParseError(...) SysPushErrorError(kFailureParseError, ## __VA_ARGS__) #if defined(DEBUG) || defined(STAGING) #define SysPushUserErrorDbg SysPushUserError #define SysPushErrorArgDbg SysPushErrorArg #define SysPushErrorGenDbg SysPushErrorGen #define SysPushErrorCryptDbg SysPushErrorCrypt #define SysPushErrorNetDbg SysPushErrorNet #define SysPushErrorMemDbg SysPushErrorMem #define SysPushErrorGenericDbg SysPushErrorGeneric #define SysPushErrorNestedDbg SysPushErrorNested #define SysPushErrorMemoryDbg SysPushErrorMemory #define SysPushErrorIODbg SysPushErrorIO #define SysPushErrorFIODbg SysPushErrorFIO #define SysPushErrorNetDbg SysPushErrorNet #define SysPushErrorAudioDbg SysPushErrorAudio #define SysPushErrorHALDbg SysPushErrorHAL #define SysPushErrorHALContextDbg SysPushErrorHALContext #define SysPushErrorCryptoDbg SysPushErrorCrypto #define SysPushErrorParamDbg SysPushErrorParam #define SysPushErrorLogicErrorDbg SysPushErrorLogicError #define SysPushErrorMathErrorDbg SysPushErrorMathError #define SysPushErrorUnavailableErrorDbg SysPushErrorUnavailableError #define SysPushErrorTimeoutErrorDbg SysPushErrorTimeoutError #define SysPushErrorWatchdogErrorDbg SysPushErrorWatchdogError #define SysPushErrorServiceErrorDbg SysPushErrorServiceError #define SysPushErrorPermissionErrorDbg SysPushErrorPermissionError #define SysPushErrorOutOfRangeDbg SysPushErrorOutOfRange #define SysPushErrorSyntaxErrorDbg SysPushErrorSyntaxError #define SysPushErrorDisconnectedDbg SysPushErrorDisconnected #define SysPushErrorUninitializedDbg SysPushErrorUninitialized #define SysPushErrorUnimplementedDbg SysPushErrorUnimplemented #define SysPushErrorCatchDbg SysPushErrorCatch #define SysPushErrorSubmissionDbg SysPushErrorSubmission #define SysPushErrorLockErrorDbg SysPushErrorLockError #define SysPushErrorSyntaxDbg SysPushErrorSyntax #define SysPushErrorNoAccessDbg SysPushErrorNoAccess #define SysPushErrorResourceMissingDbg SysPushErrorResourceMissing #define SysPushErrorResourceLockedDbg SysPushErrorResourceLocked #define SysPushErrorMalformedDataDbg SysPushErrorMalformedData #define SysPushErrorInSandboxContextDbg SysPushErrorInSandboxContext #define SysPushErrorParseErrorDbg SysPushErrorParseError #else #define SysPushUserErrorDbg(...) #define SysPushErrorArgDbg(...) #define SysPushErrorGenDbg(...) #define SysPushErrorCryptDbg(...) #define SysPushErrorNetDbg(...) #define SysPushErrorMemDbg(...) #define SysPushErrorGenericDbg(...) #define SysPushErrorNestedDbg(...) #define SysPushErrorMemoryDbg(...) #define SysPushErrorIODbg(...) #define SysPushErrorFIODbg(...) #define SysPushErrorNetDbg(...) #define SysPushErrorAudioDbg(...) #define SysPushErrorHALDbg(...) #define SysPushErrorHALContextDbg(...) #define SysPushErrorCryptoDbg(...) #define SysPushErrorParamDbg(...) #define SysPushErrorLogicErrorDbg(...) #define SysPushErrorMathErrorDbg(...) #define SysPushErrorUnavailableErrorDbg(...) #define SysPushErrorTimeoutErrorDbg(...) #define SysPushErrorWatchdogErrorDbg(...) #define SysPushErrorServiceErrorDbg(...) #define SysPushErrorPermissionErrorDbg(...) #define SysPushErrorOutOfRangeDbg(...) #define SysPushErrorSyntaxErrorDbg(...) #define SysPushErrorDisconnectedDbg(...) #define SysPushErrorUninitializedDbg(...) #define SysPushErrorUnimplementedDbg(...) #define SysPushErrorCatchDbg(...) #define SysPushErrorSubmissionDbg(...) #define SysPushErrorLockErrorDbg(...) #define SysPushErrorSyntaxDbg(...) #define SysPushErrorNoAccessDbg(...) #define SysPushErrorResourceMissingDbg(...) #define SysPushErrorResourceLockedDbg(...) #define SysPushErrorMalformedDataDbg(...) #define SysPushErrorInSandboxContextDbg(...) #define SysPushErrorParseErrorDbg(...) #endif