diff --git a/Ballance/BMapInspector/BMapInspector.cpp b/Ballance/BMapInspector/BMapInspector.cpp index 066259d..506c202 100644 --- a/Ballance/BMapInspector/BMapInspector.cpp +++ b/Ballance/BMapInspector/BMapInspector.cpp @@ -8,31 +8,61 @@ #include #include #include +#include using namespace yycc::patch::stream; namespace strop = yycc::string::op; namespace termcolor = yycc::carton::termcolor; -static bool ProcessCli() { - -} - -static void LoadVirtools() { - -} - -static void CheckRules() { - -} - -int main(int argc, char *argv[]) { - - // Show splash +static void PrintSplash() { std::cout << termcolor::colored(u8"" BMAPINSP_NAME, termcolor::Color::LightYellow) << " (based on LibCmo " LIBCMO_VER_STR ") built at " __DATE__ " " __TIME__ << std::endl - << u8"" BMAPINSP_DESC << std::endl - << std::endl; + << u8"" BMAPINSP_DESC << std::endl; +} +static std::optional AcceptArgs() { + auto request = BMapInspector::Cli::parse(); + if (request.has_value()) { + return request.value(); + } else { + using BMapInspector::Cli::Error; + + std::u8string bad_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."; + break; + case Error::BadFile: + bad_words = u8"Your specified file is invalid."; + break; + case Error::NoBallance: + bad_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."; + break; + case Error::BadEncoding: + bad_words = u8"Your specified encoding name is invalid."; + break; + case Error::BadLevel: + bad_words = u8"Your specified report level filter name is invalid."; + break; + default: + bad_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); + return std::nullopt; + } +} + +static void LoadVirtools() {} + +static void CheckRules() { // Create reporter BMapInspector::Reporter reporter; @@ -40,13 +70,21 @@ int main(int argc, char *argv[]) { BMapInspector::Ruleset::RuleCollection rule_collection; // Show rule infos 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 - << std::endl; - + << u8"Check may take few minutes. Please do not close this console..." << std::endl; + // Show report conclusion reporter.PrintConclusion(); // Print report in detail reporter.PrintReport(); - - return 0; +} + +int main(int argc, char *argv[]) { + auto args = AcceptArgs(); + if (args.has_value()) { + PrintSplash(); + std::cout << std::endl; + + CheckRules(); + } + return 0; } diff --git a/Ballance/BMapInspector/Cli.cpp b/Ballance/BMapInspector/Cli.cpp index 2ab3f3f..7afe461 100644 --- a/Ballance/BMapInspector/Cli.cpp +++ b/Ballance/BMapInspector/Cli.cpp @@ -1,63 +1,12 @@ #include "Cli.hpp" #include #include +#include namespace clap = yycc::carton::clap; namespace BMapInspector::Cli { -#pragma region Request - - Request Request::FromHelpRequest() { - return Request(RequestKind::Help, std::nullopt, std::nullopt, std::nullopt, std::nullopt); - } - - Request Request::FromVersionRequest() { - return Request(RequestKind::Version, std::nullopt, std::nullopt, std::nullopt, std::nullopt); - } - - Request Request::FromWorkRequest(Utils::ReportLevel level, - const std::u8string_view& file_path, - const std::u8string_view& encoding, - const std::u8string_view& ballance_path) { - return Request(RequestKind::Work, level, file_path, encoding, ballance_path); - } - - Request::Request(RequestKind kind, - std::optional level, - std::optional file_path, - std::optional encoding, - std::optional ballance_path) : - kind(kind), level(level), file_path(file_path), encoding(encoding), ballance_path(ballance_path) {} - - Request::~Request() {} - - RequestKind Request::GetRequestKind() const { - return this->kind; - } - - Utils::ReportLevel Request::GetLevel() const { - if (this->level.has_value()) return this->level.value(); - else throw std::logic_error("can not visit this property in current kind"); - } - - std::u8string_view Request::GetFilePath() const { - if (this->file_path.has_value()) return this->file_path.value(); - else throw std::logic_error("can not visit this property in current kind"); - } - - std::u8string_view Request::GetEncoding() const { - if (this->encoding.has_value()) return this->encoding.value(); - else throw std::logic_error("can not visit this property in current kind"); - } - - std::u8string_view Request::GetBallancePath() const { - if (this->ballance_path.has_value()) return this->ballance_path.value(); - else throw std::logic_error("can not visit this property in current kind"); - } - -#pragma endregion - #pragma region Custom Validators struct ReportLevelValidator { @@ -65,10 +14,36 @@ namespace BMapInspector::Cli { std::optional validate(const std::u8string_view& sv) const { return Utils::ParseReportLevel(sv); } }; + struct MapFileValidator { + using ReturnType = std::u8string; + std::optional validate(const std::u8string_view& sv) const { + std::filesystem::path p(sv); + if (std::filesystem::is_regular_file(p)) return std::u8string(sv); + else return std::nullopt; + } + }; + + struct BlcDirValidator { + using ReturnType = std::u8string; + std::optional validate(const std::u8string_view& sv) const { + std::filesystem::path p(sv); + auto tdb = p / u8"Database.tdb"; + if (std::filesystem::is_directory(p) && std::filesystem::is_regular_file(tdb)) return std::u8string(sv); + else return std::nullopt; + } + }; + + struct EncNameValidator { + using ReturnType = std::u8string; + std::optional validate(const std::u8string_view& sv) const { + // TODO: use checker for checking this name first. + return std::u8string(sv); + } + }; + #pragma endregion - - Result parse() { + Result> parse() { // Create options clap::option::OptionCollection opt_collection; auto opt_file = opt_collection.add_option( @@ -94,6 +69,8 @@ Default value is "info".)")); clap::summary::Summary summary(u8"" BMAPINSP_NAME, u8"yyc12345", u8"Universal", u8"" BMAPINSP_DESC); // Create application clap::application::Application app(std::move(summary), std::move(opt_collection), std::move(var_collection)); + // Create manual + clap::manual::Manual manual(app); // Create parser and parse command line arguments auto rv_parser = clap::parser::Parser::from_system(app); @@ -101,17 +78,19 @@ Default value is "info".)")); auto& parser = rv_parser.value(); // Check version and help first - if (auto help_flag = parser.get_flag_option(opt_help); help_flag.has_value()) { - return Request::FromHelpRequest(); + if (auto help_flag = parser.get_flag_option(opt_help); help_flag.has_value() && help_flag.value()) { + manual.print_help(); + return std::nullopt; } - if (auto version_flag = parser.get_flag_option(opt_version); version_flag.has_value()) { - return Request::FromVersionRequest(); + if (auto version_flag = parser.get_flag_option(opt_version); version_flag.has_value() && version_flag.value()) { + manual.print_version(); + return std::nullopt; } // Check other args std::u8string file_rv; if (parser.has_option(opt_file)) { - auto file_value = parser.get_value_option(opt_file); + auto file_value = parser.get_value_option(opt_file); if (!file_value.has_value()) return std::unexpected(Error::BadFile); file_rv = std::move(file_value.value()); } else { @@ -119,7 +98,7 @@ Default value is "info".)")); } std::u8string ballance_rv; if (parser.has_option(opt_ballance)) { - auto ballance_value = parser.get_value_option(opt_ballance); + auto ballance_value = parser.get_value_option(opt_ballance); if (!ballance_value.has_value()) return std::unexpected(Error::BadBallance); ballance_rv = std::move(ballance_value.value()); } else { @@ -127,7 +106,7 @@ Default value is "info".)")); } std::u8string encoding_rv; if (parser.has_option(opt_encoding)) { - auto encoding_value = parser.get_value_option(opt_encoding); + auto encoding_value = parser.get_value_option(opt_encoding); if (!encoding_value.has_value()) return std::unexpected(Error::BadEncoding); encoding_rv = std::move(encoding_value.value()); } else { @@ -143,7 +122,12 @@ Default value is "info".)")); } // Return result - return Request::FromWorkRequest(level_rv, file_rv, encoding_rv, ballance_rv); + return Args{ + .level = level_rv, + .file_path = file_rv, + .encoding = encoding_rv, + .ballance_path = ballance_rv, + }; } } // namespace BMapInspector::Cli diff --git a/Ballance/BMapInspector/Cli.hpp b/Ballance/BMapInspector/Cli.hpp index 4c9eff5..0a375c6 100644 --- a/Ballance/BMapInspector/Cli.hpp +++ b/Ballance/BMapInspector/Cli.hpp @@ -9,45 +9,11 @@ namespace BMapInspector::Cli { - enum class RequestKind { - Help, - Version, - Work, - }; - - class Request { - public: - static Request FromHelpRequest(); - static Request FromVersionRequest(); - static Request FromWorkRequest(Utils::ReportLevel level, - const std::u8string_view& file_path, - const std::u8string_view& encoding, - const std::u8string_view& ballance_path); - - private: - Request(RequestKind kind, - std::optional level, - std::optional file_path, - std::optional encoding, - std::optional ballance_path); - - public: - ~Request(); - YYCC_DEFAULT_COPY_MOVE(Request) - - public: - RequestKind GetRequestKind() const; - Utils::ReportLevel GetLevel() const; - std::u8string_view GetFilePath() const; - std::u8string_view GetEncoding() const; - std::u8string_view GetBallancePath() const; - - private: - RequestKind kind; ///< The kind of this request. - std::optional level; ///< The filter level. - std::optional file_path; ///< The path to loaded map file. - std::optional encoding; ///< The encoding used when loading map file. - std::optional ballance_path; ///< The path to Ballance root directory for loading resources. + struct Args { + Utils::ReportLevel level; ///< The filter level. + std::u8string file_path; ///< The path to loaded map file. + std::u8string encoding; ///< The encoding used when loading map file. + std::u8string ballance_path; ///< The path to Ballance root directory for loading resources. }; enum class Error { @@ -63,6 +29,6 @@ namespace BMapInspector::Cli { template using Result = std::expected; - Result parse(); + Result> parse(); } // namespace BMapInspector::Cli diff --git a/Ballance/BMapInspector/Ruleset.hpp b/Ballance/BMapInspector/Ruleset.hpp index 2a5a9cf..ee9c1ca 100644 --- a/Ballance/BMapInspector/Ruleset.hpp +++ b/Ballance/BMapInspector/Ruleset.hpp @@ -1,5 +1,6 @@ #pragma once #include "Utils.hpp" +#include "Reporter.hpp" #include #include #include @@ -17,7 +18,7 @@ namespace BMapInspector::Ruleset { public: virtual std::u8string_view GetRuleName() const = 0; - virtual void Check(Utils::Reporter& reporter) const = 0; + virtual void Check(Reporter& reporter) const = 0; }; class RuleCollection {