diff --git a/app/include/plasp-app/Command.h b/app/include/plasp-app/Command.h index ae4b014..d006fc4 100644 --- a/app/include/plasp-app/Command.h +++ b/app/include/plasp-app/Command.h @@ -14,12 +14,30 @@ // //////////////////////////////////////////////////////////////////////////////////////////////////// -template +template class Command { + public: + void printHelp() + { + const auto numberOfOptionGroups = std::tuple_size>(); + + std::vector optionGroupNames; + optionGroupNames.reserve(numberOfOptionGroups + 1); + optionGroupNames.emplace_back(""); + + forEach(m_optionGroups, + [&](auto &optionGroup) + { + optionGroupNames.emplace_back(optionGroup.Name); + }); + + std::cout << m_options.help(optionGroupNames) << std::endl; + } + protected: - Command(cxxopts::Options &&options) - : m_options{options} + Command() + : m_options(std::string("plasp ") + Derived::Name, std::string(Derived::Description) + ".") { forEach(m_optionGroups, [&](auto &optionGroup) @@ -39,24 +57,7 @@ class Command }); } - void printHelp() - { - const auto numberOfOptionGroups = std::tuple_size>(); - - std::vector optionGroupNames; - optionGroupNames.reserve(numberOfOptionGroups + 1); - optionGroupNames.emplace_back(""); - - forEach(m_optionGroups, - [&](auto &optionGroup) - { - optionGroupNames.emplace_back(optionGroup.Name); - }); - - std::cout << m_options.help(optionGroupNames) << std::endl; - } - - void printVersion() + static void printVersion() { std::cout << Version << std::endl; } diff --git a/app/include/plasp-app/CommandType.h b/app/include/plasp-app/CommandType.h new file mode 100644 index 0000000..0bdf22b --- /dev/null +++ b/app/include/plasp-app/CommandType.h @@ -0,0 +1,65 @@ +#ifndef __PLASP_APP__COMMAND_TYPE_H +#define __PLASP_APP__COMMAND_TYPE_H + +#include +#include + +#include +#include +#include +#include + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Command Type +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +enum class CommandType +{ + Help, + Version, + CheckSyntax, + Requirements, + PrettyPrint, + Normalize, + Translate +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +static const std::map commandNames = + { + {"help", CommandType::Help}, + {"-h", CommandType::Help}, + {"--help", CommandType::Help}, + {"version", CommandType::Version}, + {"-v", CommandType::Version}, + {"--version", CommandType::Version}, + {"check-syntax", CommandType::CheckSyntax}, + {"requirements", CommandType::Requirements}, + {"pretty-print", CommandType::PrettyPrint}, + {"normalize", CommandType::Normalize}, + {"translate", CommandType::Translate}, + }; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +const auto parseCommandType = + [](const std::string &commandString) + { + const auto matchingCommand = commandNames.find(commandString); + + if (matchingCommand == commandNames.cend()) + throw std::runtime_error(std::string("“") + commandString + "” is not a plasp command"); + + return matchingCommand->second; + }; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +using AvailableCommands = std::tuple; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +#endif diff --git a/app/include/plasp-app/commands/CommandHelp.h b/app/include/plasp-app/commands/CommandHelp.h new file mode 100644 index 0000000..99dcd12 --- /dev/null +++ b/app/include/plasp-app/commands/CommandHelp.h @@ -0,0 +1,25 @@ +#ifndef __PLASP_APP__COMMANDS__COMMAND_HELP_H +#define __PLASP_APP__COMMANDS__COMMAND_HELP_H + +#include +#include + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Command Help +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class CommandHelp : public Command +{ + public: + static constexpr auto Name = "help"; + static constexpr auto Description = "Display this help message"; + + public: + int run(int argc, char **argv); +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +#endif diff --git a/app/include/plasp-app/commands/CommandNormalize.h b/app/include/plasp-app/commands/CommandNormalize.h index d7278b2..249761f 100644 --- a/app/include/plasp-app/commands/CommandNormalize.h +++ b/app/include/plasp-app/commands/CommandNormalize.h @@ -10,11 +10,13 @@ // //////////////////////////////////////////////////////////////////////////////////////////////////// -class CommandNormalize : public Command +class CommandNormalize : public Command { public: - CommandNormalize(); + static constexpr auto Name = "normalize"; + static constexpr auto Description = "Normalize PDDL to plasp’s custom PDDL format"; + public: int run(int argc, char **argv); }; diff --git a/app/include/plasp-app/commands/CommandTranslate.h b/app/include/plasp-app/commands/CommandTranslate.h index c40b7a8..ce6e161 100644 --- a/app/include/plasp-app/commands/CommandTranslate.h +++ b/app/include/plasp-app/commands/CommandTranslate.h @@ -10,11 +10,13 @@ // //////////////////////////////////////////////////////////////////////////////////////////////////// -class CommandTranslate : public Command +class CommandTranslate : public Command { public: - CommandTranslate(); + static constexpr auto Name = "translate"; + static constexpr auto Description = "Translate PDDL and SAS to ASP"; + public: int run(int argc, char **argv); }; diff --git a/app/include/plasp-app/commands/CommandVersion.h b/app/include/plasp-app/commands/CommandVersion.h index 8b4c615..ad13fc5 100644 --- a/app/include/plasp-app/commands/CommandVersion.h +++ b/app/include/plasp-app/commands/CommandVersion.h @@ -10,11 +10,13 @@ // //////////////////////////////////////////////////////////////////////////////////////////////////// -class CommandVersion : public Command<> +class CommandVersion : public Command { public: - CommandVersion(); + static constexpr auto Name = "version"; + static constexpr auto Description = "Display version information"; + public: int run(int argc, char **argv); }; diff --git a/app/src/plasp-app/OptionGroups.cpp b/app/src/plasp-app/OptionGroups.cpp index b283045..57daf05 100644 --- a/app/src/plasp-app/OptionGroups.cpp +++ b/app/src/plasp-app/OptionGroups.cpp @@ -83,6 +83,7 @@ void OptionGroupParser::addTo(cxxopts::Options &options) ("parsing-mode", "Parsing mode (strict, compatibility)", cxxopts::value()->default_value("strict")) ("l,language", "Input language (pddl, sas, auto)", cxxopts::value()->default_value("auto")); options.parse_positional("input"); + options.positional_help("[]"); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/app/src/plasp-app/commands/CommandHelp.cpp b/app/src/plasp-app/commands/CommandHelp.cpp new file mode 100644 index 0000000..2e5674b --- /dev/null +++ b/app/src/plasp-app/commands/CommandHelp.cpp @@ -0,0 +1,79 @@ +#include + +#include + +#include + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Command Help +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +int CommandHelp::run(int argc, char **argv) +{ + colorlog::Logger logger; + + if (argc > 1) + { + try + { + switch (parseCommandType(argv[1])) + { + case CommandType::Help: + case CommandType::Version: + break; + + case CommandType::Normalize: + CommandNormalize().printHelp(); + return EXIT_SUCCESS; + + case CommandType::Translate: + CommandTranslate().printHelp(); + return EXIT_SUCCESS; + + default: + logger.log(colorlog::Priority::Error, std::string("command “") + argv[1] + "” not yet implemented"); + exit(EXIT_FAILURE); + } + } + catch (std::exception &exception) + { + } + } + + std::cout + << "ASP planning tools for PDDL." << std::endl + << "Usage:" << std::endl + << " plasp []" << std::endl << std::endl + << " available commands:" << std::endl; + + AvailableCommands availableCommands; + + size_t lengthOfLongestCommandName = 0; + + forEach(availableCommands, + [&](const auto &command) + { + lengthOfLongestCommandName = std::max(lengthOfLongestCommandName, std::strlen(command.Name)); + }); + + const auto printSpaces = + [](const auto numberOfSpaces) + { + for (auto i = static_cast(0); i < numberOfSpaces; i++) + std::cout << " "; + }; + + forEach(availableCommands, + [&](const auto &command) + { + const auto lengthOfCommandName = std::strlen(command.Name); + + std::cout << " " << command.Name; + printSpaces(lengthOfLongestCommandName - lengthOfCommandName + 2); + std::cout << command.Description << std::endl; + }); + + return EXIT_SUCCESS; +} diff --git a/app/src/plasp-app/commands/CommandNormalize.cpp b/app/src/plasp-app/commands/CommandNormalize.cpp index 3f52514..6f316ad 100644 --- a/app/src/plasp-app/commands/CommandNormalize.cpp +++ b/app/src/plasp-app/commands/CommandNormalize.cpp @@ -27,13 +27,6 @@ // //////////////////////////////////////////////////////////////////////////////////////////////////// -CommandNormalize::CommandNormalize() -: Command(cxxopts::Options("plasp normalize", "Normalize PDDL to plasp’s custom PDDL format.")) -{ -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - int CommandNormalize::run(int argc, char **argv) { parseOptions(argc, argv); diff --git a/app/src/plasp-app/commands/CommandTranslate.cpp b/app/src/plasp-app/commands/CommandTranslate.cpp index 97f195f..83c52e5 100644 --- a/app/src/plasp-app/commands/CommandTranslate.cpp +++ b/app/src/plasp-app/commands/CommandTranslate.cpp @@ -30,13 +30,6 @@ // //////////////////////////////////////////////////////////////////////////////////////////////////// -CommandTranslate::CommandTranslate() -: Command(cxxopts::Options("plasp translate", "Translate PDDL to ASP.")) -{ -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - int CommandTranslate::run(int argc, char **argv) { parseOptions(argc, argv); diff --git a/app/src/plasp-app/commands/CommandVersion.cpp b/app/src/plasp-app/commands/CommandVersion.cpp index 7b9a52b..45f201c 100644 --- a/app/src/plasp-app/commands/CommandVersion.cpp +++ b/app/src/plasp-app/commands/CommandVersion.cpp @@ -6,13 +6,6 @@ // //////////////////////////////////////////////////////////////////////////////////////////////////// -CommandVersion::CommandVersion() -: Command(cxxopts::Options("plasp version", "Display version information.")) -{ -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - int CommandVersion::run(int, char **) { printVersion(); diff --git a/app/src/plasp-app/main.cpp b/app/src/plasp-app/main.cpp index b009804..c4cb6ad 100644 --- a/app/src/plasp-app/main.cpp +++ b/app/src/plasp-app/main.cpp @@ -8,10 +8,8 @@ #include #include +#include #include -#include -#include -#include //////////////////////////////////////////////////////////////////////////////////////////////////// // @@ -19,65 +17,14 @@ // //////////////////////////////////////////////////////////////////////////////////////////////////// -enum class CommandType -{ - Help, - Version, - CheckSyntax, - Requirements, - PrettyPrint, - Normalize, - Translate -}; - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -static const std::map commandNames = - { - {"help", CommandType::Help}, - {"-h", CommandType::Help}, - {"--help", CommandType::Help}, - {"version", CommandType::Version}, - {"-v", CommandType::Version}, - {"--version", CommandType::Version}, - {"check-syntax", CommandType::CheckSyntax}, - {"requirements", CommandType::Requirements}, - {"pretty-print", CommandType::PrettyPrint}, - {"normalize", CommandType::Normalize}, - {"translate", CommandType::Translate}, - }; - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -const auto parseCommandType = - [](const std::string &commandString) - { - const auto matchingCommand = commandNames.find(commandString); - - if (matchingCommand == commandNames.cend()) - throw std::runtime_error(std::string("“") + commandString + "” is not a plasp command"); - - return matchingCommand->second; - }; - -//////////////////////////////////////////////////////////////////////////////////////////////////// - int main(int argc, char **argv) { - const auto printHelp = - [&]() - { - // TODO: add list of available commands - std::cout - << "ASP planning tools for PDDL." << std::endl - << "Usage: plasp []" << std::endl; - }; - colorlog::Logger logger; if (argc < 2) { - printHelp(); + CommandHelp().run(argc - 1, &argv[1]); + return EXIT_FAILURE; } @@ -86,16 +33,19 @@ int main(int argc, char **argv) switch (parseCommandType(argv[1])) { case CommandType::Help: - printHelp(); - return EXIT_SUCCESS; + return CommandHelp().run(argc - 1, &argv[1]); + case CommandType::Version: return CommandVersion().run(argc - 1, &argv[1]); - return EXIT_SUCCESS; + case CommandType::Normalize: return CommandNormalize().run(argc - 1, &argv[1]); + case CommandType::Translate: return CommandTranslate().run(argc - 1, &argv[1]); + default: + logger.log(colorlog::Priority::Error, std::string("command “") + argv[1] + "” not yet implemented"); exit(EXIT_FAILURE); } } @@ -103,7 +53,9 @@ int main(int argc, char **argv) { logger.log(colorlog::Priority::Error, exception.what()); std::cout << std::endl; - printHelp(); + + CommandHelp().run(argc - 1, &argv[1]); + return EXIT_FAILURE; }