160 lines
3.3 KiB
C++
160 lines
3.3 KiB
C++
/***
|
|
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: ErrorStack.cpp
|
|
Date: 2022-11-29
|
|
Author: Reece
|
|
***/
|
|
#include <Source/RuntimeInternal.hpp>
|
|
#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<ThreadMessage> pHead)
|
|
{
|
|
pStack->pHead = pHead;
|
|
}
|
|
|
|
AuSPtr<ThreadMessage> 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 ErrorStack::ErrorStack()
|
|
{
|
|
auto pStack = this;
|
|
|
|
if (!tlsErrorStackBase)
|
|
{
|
|
tlsErrorStackBase = pStack;
|
|
return;
|
|
}
|
|
|
|
ErrorStackAccessor dumb;
|
|
auto itr = tlsErrorStackBase;
|
|
while (auto pNext = dumb.GetNext(itr))
|
|
{
|
|
itr = pNext;
|
|
}
|
|
|
|
dumb.SetNext(itr, pStack);
|
|
}
|
|
|
|
AUKN_SYM ErrorStack::~ErrorStack()
|
|
{
|
|
auto pStack = this;
|
|
|
|
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<ThreadMessage> pMessage)
|
|
{
|
|
ErrorStackAccessor dumb;
|
|
if (!dumb.GetHead(pStack))
|
|
{
|
|
dumb.SetHead(pStack, pMessage);
|
|
return;
|
|
}
|
|
|
|
AuSPtr<ThreadMessage> 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<ThreadMessage> pMessage)
|
|
{
|
|
ErrorStackAccessor dumb;
|
|
auto itr = tlsErrorStackBase;
|
|
|
|
if (itr)
|
|
{
|
|
AddToInstance(itr, pMessage);
|
|
while (auto pNext = dumb.GetNext(itr))
|
|
{
|
|
AddToInstance(itr, pMessage);
|
|
itr = pNext;
|
|
}
|
|
}
|
|
}
|
|
} |