diff --git a/Ballance/BMapInspector/BMapInspector.cpp b/Ballance/BMapInspector/BMapInspector.cpp index 506c202..1065aab 100644 --- a/Ballance/BMapInspector/BMapInspector.cpp +++ b/Ballance/BMapInspector/BMapInspector.cpp @@ -13,9 +13,10 @@ using namespace yycc::patch::stream; namespace strop = yycc::string::op; namespace termcolor = yycc::carton::termcolor; +using termcolor::Color; static void PrintSplash() { - std::cout << termcolor::colored(u8"" BMAPINSP_NAME, termcolor::Color::LightYellow) + std::cout << termcolor::colored(u8"" BMAPINSP_NAME, Color::LightYellow) << " (based on LibCmo " LIBCMO_VER_STR ") built at " __DATE__ " " __TIME__ << std::endl << u8"" BMAPINSP_DESC << std::endl; } @@ -27,44 +28,47 @@ static std::optional AcceptArgs() { } else { using BMapInspector::Cli::Error; - std::u8string bad_words; + std::u8string err_words; switch (request.error()) { case Error::BadParse: - bad_words = u8"Can not parse given command line argument."; break; - case Error::NoFile: - bad_words = u8"You must specify a file for checking."; + err_words = u8"Can not parse given command line argument."; + break; + case Error::NoFile: + err_words = u8"You must specify a file for checking."; break; case Error::BadFile: - bad_words = u8"Your specified file is invalid."; + err_words = u8"Your specified file is invalid."; break; case Error::NoBallance: - bad_words = u8"You must specify Ballance root directory for finding resources."; + err_words = u8"You must specify Ballance root directory for finding resources."; break; case Error::BadBallance: - bad_words = u8"Your specified Ballance root directory is invalid."; + err_words = u8"Your specified Ballance root directory is invalid."; break; case Error::BadEncoding: - bad_words = u8"Your specified encoding name is invalid."; + err_words = u8"Your specified encoding name is invalid."; break; case Error::BadLevel: - bad_words = u8"Your specified report level filter name is invalid."; + err_words = u8"Your specified report level filter name is invalid."; break; default: - bad_words = u8"Unknown error."; + err_words = u8"Unknown error."; break; } - termcolor::cprintln(bad_words, termcolor::Color::Red); - termcolor::cprintln(u8"Please browse manual or use -h switch to see help first.", termcolor::Color::Red); + termcolor::cprintln(err_words, Color::Red); + termcolor::cprintln(u8"Please browse manual or use -h switch to see help first.", Color::Red); return std::nullopt; } } -static void LoadVirtools() {} +static std::optional LoadVirtools(BMapInspector::Cli::Args& args) { + return std::nullopt; +} -static void CheckRules() { +static void CheckRules(BMapInspector::Ruleset::RuleContext& ctx) { // Create reporter - BMapInspector::Reporter reporter; + BMapInspector::Reporter::Reporter reporter; // Get rule collection BMapInspector::Ruleset::RuleCollection rule_collection; @@ -72,19 +76,45 @@ static void CheckRules() { std::cout << strop::printf(u8"Total %" PRIuSIZET " rule(s) are loaded.", rule_collection.GetRuleCount()) << std::endl << u8"Check may take few minutes. Please do not close this console..." << std::endl; + // Check rules one by one + for (auto* rule : rule_collection.GetRules()) { + rule->Check(reporter, ctx); + } + // Show report conclusion - reporter.PrintConclusion(); + auto digest = reporter.GetDigest(); + termcolor::cprintln(strop::printf(u8"Total %" PRIuSIZET " error(s), %" PRIuSIZET " warning(s) and %" PRIuSIZET " info(s).", + digest.cnt_err, + digest.cnt_warn, + digest.cnt_info), + Color::LightYellow); // Print report in detail - reporter.PrintReport(); + using BMapInspector::Utils::ReportLevel; + for (const auto& report : reporter.GetReports()) { + switch (report.level) { + case ReportLevel::Error: + termcolor::cprintln(strop::printf(u8"[ERROR] [RULE: %s] %s", report.rule.c_str(), report.content.c_str()), Color::Red); + break; + case ReportLevel::Warning: + termcolor::cprintln(strop::printf(u8"[WARNING] [RULE: %s] %s", report.rule.c_str(), report.content.c_str()), Color::Yellow); + break; + case ReportLevel::Info: + termcolor::cprintln(strop::printf(u8"[INFO] [RULE: %s] %s", report.rule.c_str(), report.content.c_str()), Color::White); + break; + } + } } -int main(int argc, char *argv[]) { +int main(int argc, char* argv[]) { auto args = AcceptArgs(); if (args.has_value()) { PrintSplash(); std::cout << std::endl; - CheckRules(); + auto ctx = LoadVirtools(args.value()); + if (ctx.has_value()) { + CheckRules(ctx.value()); + } } return 0; } diff --git a/Ballance/BMapInspector/Cli.cpp b/Ballance/BMapInspector/Cli.cpp index 7afe461..abe16ea 100644 --- a/Ballance/BMapInspector/Cli.cpp +++ b/Ballance/BMapInspector/Cli.cpp @@ -54,7 +54,7 @@ This field is required.)")); This field is required.)")); auto opt_encoding = opt_collection.add_option( clap::option::Option(u8"e", u8"encoding", u8"ENC", u8R"(The encoding used when loading this map file. -Frequently used encoding is "cp1252" and "gbk". +Frequently used encodings are "cp1252" and "gbk". Default value is "cp1252".)")); auto opt_level = opt_collection.add_option( clap::option::Option(u8"l", u8"level", u8"LEVEL", u8R"(Set the filter level for checker output. diff --git a/Ballance/BMapInspector/Reporter.cpp b/Ballance/BMapInspector/Reporter.cpp index fe23956..e79f2c0 100644 --- a/Ballance/BMapInspector/Reporter.cpp +++ b/Ballance/BMapInspector/Reporter.cpp @@ -1,15 +1,10 @@ #include "Reporter.hpp" -#include #include -#include -#include #include -using namespace yycc::patch::stream; namespace strop = yycc::string::op; -namespace termcolor = yycc::carton::termcolor; -namespace BMapInspector { +namespace BMapInspector::Reporter { #pragma region Reporter @@ -57,51 +52,28 @@ namespace BMapInspector { va_end(argptr); } - void Reporter::PrintConclusion() const { - // Conclude count - size_t cnt_err = 0, cnt_warn = 0, cnt_info = 0; + ReporterDigest Reporter::GetDigest() const { + ReporterDigest digest{.cnt_err = 0, .cnt_warn = 0, .cnt_info = 0}; for (const auto &report : this->reports) { switch (report.level) { case Utils::ReportLevel::Error: - ++cnt_err; + ++digest.cnt_err; break; case Utils::ReportLevel::Warning: - ++cnt_warn; + ++digest.cnt_warn; break; case Utils::ReportLevel::Info: - ++cnt_info; + ++digest.cnt_info; break; } } - - // Show in console - termcolor::cprintln(strop::printf(u8"Total %" PRIuSIZET " error(s), %" PRIuSIZET " warning(s) and %" PRIuSIZET " info(s).", - cnt_err, - cnt_warn, - cnt_info), - termcolor::Color::LightBlue); + return digest; } - void Reporter::PrintReport() const { - // Print all entries by different color - for (const auto &report : this->reports) { - switch (report.level) { - case Utils::ReportLevel::Error: - termcolor::cprintln(strop::printf(u8"[ERROR] [RULE: %s] %s", report.rule.c_str(), report.content.c_str()), - termcolor::Color::LightRed); - break; - case Utils::ReportLevel::Warning: - termcolor::cprintln(strop::printf(u8"[WARNING] [RULE: %s] %s", report.rule.c_str(), report.content.c_str()), - termcolor::Color::LightYellow); - break; - case Utils::ReportLevel::Info: - termcolor::cprintln(strop::printf(u8"[INFO] [RULE: %s] %s", report.rule.c_str(), report.content.c_str()), - termcolor::Color::Default); - break; - } - } + const std::vector &Reporter::GetReports() const { + return this->reports; } #pragma endregion -} // namespace BMapInspector::Utils +} // namespace BMapInspector::Reporter diff --git a/Ballance/BMapInspector/Reporter.hpp b/Ballance/BMapInspector/Reporter.hpp index 6ca987e..f273ed3 100644 --- a/Ballance/BMapInspector/Reporter.hpp +++ b/Ballance/BMapInspector/Reporter.hpp @@ -6,12 +6,18 @@ #include #include -namespace BMapInspector { +namespace BMapInspector::Reporter { struct Report { - Utils::ReportLevel level; ///< The level of this report. - std::u8string rule; ///< The name of rule adding this report. - std::u8string content; ///< The content of this report. + Utils::ReportLevel level; ///< The level of this report. + std::u8string rule; ///< The name of rule adding this report. + std::u8string content; ///< The content of this report. + }; + + struct ReporterDigest { + size_t cnt_err; ///< The count of error report. + size_t cnt_warn; ///< The count of warning report. + size_t cnt_info; ///< The count of info report. }; class Reporter { @@ -32,11 +38,11 @@ namespace BMapInspector { void FormatError(const std::u8string_view& rule, const char8_t* fmt, ...); public: - void PrintConclusion() const; - void PrintReport() const; + ReporterDigest GetDigest() const; + const std::vector& GetReports() const; private: std::vector reports; }; -} // namespace BMapInspector::Utils +} // namespace BMapInspector diff --git a/Ballance/BMapInspector/Ruleset.cpp b/Ballance/BMapInspector/Ruleset.cpp index b73344f..36e0d37 100644 --- a/Ballance/BMapInspector/Ruleset.cpp +++ b/Ballance/BMapInspector/Ruleset.cpp @@ -2,6 +2,28 @@ namespace BMapInspector::Ruleset { +#pragma region Rule Context + + RuleContext::RuleContext() : m_Ctx(nullptr) {} + + RuleContext::~RuleContext() {} + + LibCmo::CK2::CKContext* RuleContext::GetCKContext() { + return this->m_Ctx; + } + + YYCC_IMPL_MOVE_CTOR(RuleContext, rhs) : m_Ctx(rhs.m_Ctx) { + rhs.m_Ctx = nullptr; + } + + YYCC_IMPL_MOVE_OPER(RuleContext, rhs) { + this->m_Ctx = rhs.m_Ctx; + rhs.m_Ctx = nullptr; + return *this; + } + +#pragma endregion + #pragma region IRule IRule::IRule() {} diff --git a/Ballance/BMapInspector/Ruleset.hpp b/Ballance/BMapInspector/Ruleset.hpp index ee9c1ca..7680d37 100644 --- a/Ballance/BMapInspector/Ruleset.hpp +++ b/Ballance/BMapInspector/Ruleset.hpp @@ -10,6 +10,20 @@ namespace BMapInspector::Ruleset { + class RuleContext { + public: + RuleContext(); + ~RuleContext(); + YYCC_DELETE_COPY(RuleContext) + YYCC_DECL_MOVE(RuleContext) + + public: + LibCmo::CK2::CKContext *GetCKContext(); + + private: + LibCmo::CK2::CKContext *m_Ctx; + }; + class IRule { public: IRule(); @@ -18,7 +32,7 @@ namespace BMapInspector::Ruleset { public: virtual std::u8string_view GetRuleName() const = 0; - virtual void Check(Reporter& reporter) const = 0; + virtual void Check(Reporter::Reporter& reporter, RuleContext& ctx) const = 0; }; class RuleCollection {