diff --git a/oscar64/Errors.cpp b/oscar64/Errors.cpp index ff29cf5..5522e47 100644 --- a/oscar64/Errors.cpp +++ b/oscar64/Errors.cpp @@ -35,7 +35,7 @@ void Errors::Error(const Location& loc, ErrorID eid, const char* msg, const char else fprintf(stderr, "%s(%d, %d) : %s %d: %s\n", loc.mFileName, loc.mLine, loc.mColumn, level, eid, msg); - if (mErrorCount > 10) + if (mErrorCount > 10 || eid >= EFATAL_GENERIC) exit(20); } diff --git a/oscar64/Errors.h b/oscar64/Errors.h index dcf4a97..967cf6c 100644 --- a/oscar64/Errors.h +++ b/oscar64/Errors.h @@ -36,7 +36,6 @@ enum ErrorID EERR_RUNTIME_CODE, EERR_UNIMPLEMENTED, EERR_COMMAND_LINE, - EERR_OUT_OF_MEMORY, EERR_OBJECT_NOT_FOUND, EERR_SYNTAX, EERR_EXECUTION_FAILED, @@ -86,6 +85,10 @@ enum ErrorID ERRR_INVALID_NUMBER, EERR_INVALID_PREPROCESSOR, + + EFATAL_GENERIC = 4000, + EFATAL_OUT_OF_MEMORY, + EFATAL_MACRO_EXPANSION_DEPTH, }; class Errors diff --git a/oscar64/Scanner.cpp b/oscar64/Scanner.cpp index 535736b..c1541d6 100644 --- a/oscar64/Scanner.cpp +++ b/oscar64/Scanner.cpp @@ -318,6 +318,7 @@ Scanner::Scanner(Errors* errors, Preprocessor* preprocessor) mAssemblerMode = false; mPreprocessorMode = false; mMacroExpansion = nullptr; + mMacroExpansionDepth = 0; mDefines = new MacroDict(); mDefineArguments = nullptr; @@ -817,6 +818,9 @@ void Scanner::NextToken(void) ex->mChar = mTokenChar; mMacroExpansion = ex; + mMacroExpansionDepth++; + if (mMacroExpansionDepth > 1024) + mErrors->Error(mLocation, EFATAL_MACRO_EXPANSION_DEPTH, "Maximum macro expansion depth exceeded", mTokenIdent); mLine = def->mString; mOffset = 0; NextChar(); @@ -1812,6 +1816,8 @@ bool Scanner::NextChar(void) delete mMacroExpansion; mMacroExpansion = mac; + mMacroExpansionDepth--; + return true; } else if (mPreprocessor->NextLine()) diff --git a/oscar64/Scanner.h b/oscar64/Scanner.h index 51d8b0a..2c61d7d 100644 --- a/oscar64/Scanner.h +++ b/oscar64/Scanner.h @@ -259,6 +259,8 @@ protected: MacroDict* mDefinedArguments; } * mMacroExpansion; + int mMacroExpansionDepth; + MacroDict* mDefines, * mDefineArguments; Token mUngetToken;