/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: ErrorStack.cpp Date: 2022-11-29 Author: Reece ***/ #include #include "Debug.hpp" #include "ErrorStack.hpp" namespace Aurora::Debug { struct ErrorStackAccessor { void SetNext(ErrorStack *pStack, ErrorStack *pNext) { pStack->pNext = pNext; } ErrorStack *GetNext(ErrorStack *pStack) { return pStack->pNext; } void SetHead(ErrorStack *pStack, AuSPtr pHead) { pStack->pHead = pHead; } AuSPtr GetHead(ErrorStack *pStack) { return pStack->pHead; } }; AUKN_SYM AuString ThreadMessage::ToString() { if (this->pStringMessage) { return *this->pStringMessage; } if (eFailureCategory) { return fmt::format("Debug::EFailureCategory = {}", (AuUInt)*eFailureCategory); } if (optOsErrorCode) { return fmt::format("OS = {}", (AuUInt)*optOsErrorCode); } return "Unknown error."; } static thread_local ErrorStack *tlsErrorStackBase; AUKN_SYM void PushStack(ErrorStack *pStack) { if (!tlsErrorStackBase) { tlsErrorStackBase = pStack; return; } ErrorStackAccessor dumb; auto itr = tlsErrorStackBase; while (auto pNext = dumb.GetNext(itr)) { itr = pNext; } dumb.SetNext(itr, pStack); } AUKN_SYM void PopStack(ErrorStack *pStack) { if (!tlsErrorStackBase) { return; } ErrorStackAccessor dumb; auto itr = tlsErrorStackBase; if (itr == pStack) { tlsErrorStackBase = nullptr; return; } while (auto pNext = dumb.GetNext(itr)) { if (pNext == pStack) { dumb.SetNext(pStack, {}); return; } itr = pNext; } } static void AddToInstance(ErrorStack *pStack, AuSPtr pMessage) { ErrorStackAccessor dumb; if (!dumb.GetHead(pStack)) { dumb.SetHead(pStack, pMessage); return; } AuSPtr pMessage2 { dumb.GetHead(pStack) }; if (pMessage2 == pMessage) { return; } while (auto pNext = pMessage2->pNextThreadMesage) { if (pNext == pMessage) { return; } pMessage2 = pNext; } pMessage2->pNextThreadMesage = pMessage; } ////////////////////////////////////////////////////////////////// // internal api: bool ShouldPushErrorStackInternal() { return bool(tlsErrorStackBase); } void PushErrorStackInternal(AuSPtr pMessage) { ErrorStackAccessor dumb; auto itr = tlsErrorStackBase; if (itr) { AddToInstance(itr, pMessage); while (auto pNext = dumb.GetNext(itr)) { AddToInstance(itr, pMessage); itr = pNext; } } } }