#ifndef KVERRORSTACK_H #define KVERRORSTACK_H #include "ikeyvaluessystem.h" // a simple class to keep track of a stack of valid parsed symbols const int MAX_ERROR_STACK = 64; class CKeyValuesErrorStack { public: CKeyValuesErrorStack() : m_pFilename("NULL"), m_errorIndex(0), m_maxErrorIndex(0), m_bEncounteredErrors(false) {} void SetFilename(const char* pFilename) { m_pFilename = pFilename; m_maxErrorIndex = 0; } // entering a new keyvalues block, save state for errors // Not save symbols instead of pointers because the pointers can move! int Push(int symName) { if (m_errorIndex < MAX_ERROR_STACK) { m_errorStack[m_errorIndex] = symName; } m_errorIndex++; m_maxErrorIndex = MAX(m_maxErrorIndex, (m_errorIndex - 1)); return m_errorIndex - 1; } // exiting block, error isn't in this block, remove. void Pop() { m_errorIndex--; Assert(m_errorIndex >= 0); } // Allows you to keep the same stack level, but change the name as you parse peers void Reset(int stackLevel, int symName) { Assert(stackLevel >= 0 && stackLevel < m_errorIndex); if (stackLevel < MAX_ERROR_STACK) m_errorStack[stackLevel] = symName; } // Hit an error, report it and the parsing stack for context void ReportError(const char* pError) { Warning(eDLL_T::COMMON, "KeyValues Error: %s in file %s\n", pError, m_pFilename); for (int i = 0; i < m_maxErrorIndex; i++) { if (i < MAX_ERROR_STACK && m_errorStack[i] != INVALID_KEY_SYMBOL) { if (i < m_errorIndex) { Warning(eDLL_T::COMMON, "%s, ", KeyValuesSystem()->GetStringForSymbol(m_errorStack[i])); } else { Warning(eDLL_T::COMMON, "(*%s*), ", KeyValuesSystem()->GetStringForSymbol(m_errorStack[i])); } } } Warning(eDLL_T::COMMON, "\n"); m_bEncounteredErrors = true; } bool EncounteredAnyErrors() { return m_bEncounteredErrors; } void ClearErrorFlag() { m_bEncounteredErrors = false; } private: int m_errorStack[MAX_ERROR_STACK]; const char* m_pFilename; int m_errorIndex; int m_maxErrorIndex; bool m_bEncounteredErrors; }; inline CKeyValuesErrorStack g_KeyValuesErrorStack; #endif // KVERRORSTACK_H