diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.cpp b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.cpp index 5f10e461..7fca4d7c 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.cpp +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderMenuList.cpp @@ -37,10 +37,25 @@ bool AssetLoaderMenuList::LoadFromRaw(const std::string& assetName, ISearchPath* return std::move(foundFileToInclude.m_stream); }); - if(!reader.ReadMenuFile()) + const auto menuFileResult = reader.ReadMenuFile(); + if(menuFileResult) { - std::cout << "Could not read menu list \"" << assetName << "\"\n"; + std::cout << "Successfully read menu list \"" << assetName << "\":\n"; + + std::cout << " " << menuFileResult->m_menus_to_load.size() << " menus to load:\n"; + for (const auto& menuToLoad : menuFileResult->m_menus_to_load) + std::cout << " " << menuToLoad << "\n"; + + std::cout << " " << menuFileResult->m_menus.size() << " menus:\n"; + for (const auto& menu : menuFileResult->m_menus) + std::cout << " " << menu->m_name << "\n"; + + std::cout << " " << menuFileResult->m_functions.size() << " functions:\n"; + for (const auto& function : menuFileResult->m_functions) + std::cout << " " << function->m_name << "\n"; } + else + std::cout << "Could not read menu list \"" << assetName << "\"\n"; return true; } diff --git a/src/ObjLoading/Parsing/Menu/Domain/MenuParsingResult.h b/src/ObjLoading/Parsing/Menu/Domain/MenuParsingResult.h new file mode 100644 index 00000000..5977da6b --- /dev/null +++ b/src/ObjLoading/Parsing/Menu/Domain/MenuParsingResult.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +#include "CommonFunctionDef.h" +#include "CommonMenuDef.h" + +class MenuParsingResult +{ +public: + std::vector> m_menus; + std::vector> m_functions; + std::vector m_menus_to_load; +}; diff --git a/src/ObjLoading/Parsing/Menu/MenuFileParser.cpp b/src/ObjLoading/Parsing/Menu/MenuFileParser.cpp index aa23b41e..ee852dbf 100644 --- a/src/ObjLoading/Parsing/Menu/MenuFileParser.cpp +++ b/src/ObjLoading/Parsing/Menu/MenuFileParser.cpp @@ -80,3 +80,8 @@ const std::vector& MenuFileParser::GetTestsForState return m_global_scope_tests; } + +MenuFileParserState* MenuFileParser::GetState() const +{ + return m_state.get(); +} diff --git a/src/ObjLoading/Parsing/Menu/MenuFileParser.h b/src/ObjLoading/Parsing/Menu/MenuFileParser.h index 4c1aca4c..253558c9 100644 --- a/src/ObjLoading/Parsing/Menu/MenuFileParser.h +++ b/src/ObjLoading/Parsing/Menu/MenuFileParser.h @@ -1,5 +1,6 @@ #pragma once +#include "Utils/ClassUtils.h" #include "MenuFileParserState.h" #include "Parsing/Simple/SimpleLexer.h" #include "Parsing/Simple/SimpleParserValue.h" @@ -27,4 +28,5 @@ protected: public: MenuFileParser(SimpleLexer* lexer, MenuFeatureLevel featureLevel); + _NODISCARD MenuFileParserState* GetState() const; }; diff --git a/src/ObjLoading/Parsing/Menu/MenuFileReader.cpp b/src/ObjLoading/Parsing/Menu/MenuFileReader.cpp index 4b131f3e..f5759106 100644 --- a/src/ObjLoading/Parsing/Menu/MenuFileReader.cpp +++ b/src/ObjLoading/Parsing/Menu/MenuFileReader.cpp @@ -68,14 +68,59 @@ void MenuFileReader::SetupStreamProxies() m_stream = m_open_streams.back().get(); } -bool MenuFileReader::ReadMenuFile() +bool MenuFileReader::IsValidEndState(const MenuFileParserState* state) const +{ + if(state->m_current_item) + { + std::cout << "In \"" << m_file_name << "\": Unclosed item at end of file!\n"; + return false; + } + + if(state->m_current_menu) + { + std::cout << "In \"" << m_file_name << "\": Unclosed menu at end of file!\n"; + return false; + } + + if(state->m_current_function) + { + std::cout << "In \"" << m_file_name << "\": Unclosed function at end of file!\n"; + return false; + } + + if(state->m_in_global_scope) + { + std::cout << "In \"" << m_file_name << "\": Did not close global scope!\n"; + return false; + } + + return true; +} + +std::unique_ptr MenuFileReader::CreateParsingResult(MenuFileParserState* state) const +{ + auto result = std::make_unique(); + result->m_menus = std::move(state->m_menus); + result->m_functions = std::move(state->m_functions); + result->m_menus_to_load = std::move(state->m_menus_to_load); + + return result; +} + +std::unique_ptr MenuFileReader::ReadMenuFile() { const auto lexer = std::make_unique(m_stream, SimpleLexer::Config{false, true, false}); const auto parser = std::make_unique(lexer.get(), m_feature_level); - if (parser->Parse()) - return true; + if (!parser->Parse()) + { + std::cout << "Parsing menu file failed!" << std::endl; + return nullptr; + } - std::cout << "Parsing menu file failed!" << std::endl; - return false; + auto* parserEndState = parser->GetState(); + if (!IsValidEndState(parserEndState)) + return nullptr; + + return CreateParsingResult(parserEndState); } diff --git a/src/ObjLoading/Parsing/Menu/MenuFileReader.h b/src/ObjLoading/Parsing/Menu/MenuFileReader.h index 5e4abcde..f72cc57e 100644 --- a/src/ObjLoading/Parsing/Menu/MenuFileReader.h +++ b/src/ObjLoading/Parsing/Menu/MenuFileReader.h @@ -4,7 +4,9 @@ #include #include +#include "MenuFileParserState.h" #include "Domain/MenuFeatureLevel.h" +#include "Domain/MenuParsingResult.h" #include "Parsing/IParserLineStream.h" class MenuFileReader @@ -23,9 +25,12 @@ private: void SetupDefinesProxy(); void SetupStreamProxies(); + bool IsValidEndState(const MenuFileParserState* state) const; + std::unique_ptr CreateParsingResult(MenuFileParserState* state) const; + public: MenuFileReader(std::istream& stream, std::string fileName, MenuFeatureLevel featureLevel); MenuFileReader(std::istream& stream, std::string fileName, MenuFeatureLevel featureLevel, include_callback_t includeCallback); - bool ReadMenuFile(); + std::unique_ptr ReadMenuFile(); };