diff --git a/.ci/Dockerfile-arch-latest b/.ci/Dockerfile-arch-latest index af2962f..c641a90 100644 --- a/.ci/Dockerfile-arch-latest +++ b/.ci/Dockerfile-arch-latest @@ -3,7 +3,7 @@ FROM archimg/base-devel:latest ARG toolchain RUN pacman -Sy -RUN pacman -S --noconfirm boost cmake git ninja re2c +RUN pacman -S --noconfirm cmake git ninja re2c RUN if [ "${toolchain}" = "clang" ]; then pacman -S --noconfirm clang; fi VOLUME /app diff --git a/.ci/Dockerfile-ubuntu-18.04 b/.ci/Dockerfile-ubuntu-18.04 index bb07059..359b758 100644 --- a/.ci/Dockerfile-ubuntu-18.04 +++ b/.ci/Dockerfile-ubuntu-18.04 @@ -3,7 +3,7 @@ FROM ubuntu:18.04 ARG toolchain RUN apt-get update -RUN apt-get install -y libboost-all-dev cmake git ninja-build re2c +RUN apt-get install -y cmake git ninja-build re2c RUN if [ "${toolchain}" = "gcc" ]; then apt-get install -y g++; fi RUN if [ "${toolchain}" = "clang" ]; then apt-get install -y clang; fi diff --git a/.gitmodules b/.gitmodules index 4203c3c..5e1ec92 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "lib/catch"] path = lib/catch url = https://github.com/catchorg/Catch2 +[submodule "lib/cxxopts"] + path = lib/cxxopts + url = https://github.com/jarro2783/cxxopts diff --git a/README.md b/README.md index 5edb50a..de3af7c 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ With the option `--simplify`, output formulas are simplified by applying several ## Building -`anthem` requires [CMake](https://cmake.org/) and [Boost](http://www.boost.org/) for building. +`anthem` requires [CMake](https://cmake.org/) for building. After installing the dependencies, `anthem` is built with a C++17 compiler (GCC ≥ 7.3 or clang ≥ 5.0). ```bash diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 5696449..c56a1d3 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -1,7 +1,5 @@ set(target anthem-app) -find_package(Boost 1.55.0 COMPONENTS program_options system filesystem REQUIRED) - file(GLOB core_sources "*.cpp") file(GLOB core_headers "*.h") @@ -11,11 +9,10 @@ set(sources ) set(includes - ${Boost_INCLUDE_DIRS} + ${PROJECT_SOURCE_DIR}/lib/cxxopts/include ) set(libraries - ${Boost_LIBRARIES} anthem ) diff --git a/app/main.cpp b/app/main.cpp index b677204..1399cdd 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include #include @@ -10,63 +10,70 @@ int main(int argc, char **argv) { anthem::Context context; - namespace po = boost::program_options; + cxxopts::Options options("anthem", "Translate ASP programs to the language of first-order theorem provers."); - po::options_description description("Allowed options"); - description.add_options() - ("help,h", "Display this help message") - ("version,v", "Display version information") - ("input,i", po::value>(), "Input files") - ("simplify,s", po::bool_switch(&context.performSimplification), "Simplify the output") - ("complete,c", po::bool_switch(&context.performCompletion), "Perform completion") - ("color", po::value()->default_value("auto"), "Colorize output (always, never, auto)") - ("parentheses", po::value()->default_value("normal"), "Parenthesis style (normal, full)") - ("log-priority,p", po::value()->default_value("warning"), "Log messages starting from this priority (debug, info, warning, error)"); + options.add_options() + ("h,help", "Display this help message") + ("v,version", "Display version information") + ("i,input", "Input files", cxxopts::value>()) + ("s,simplify", "Simplify the output") + ("c,complete", "Perform completion") + ("color", "Colorize output (always, never, auto)", cxxopts::value()->default_value("auto")) + ("parentheses", "Parenthesis style (normal, full)", cxxopts::value()->default_value("normal")) + ("p,log-priority", "Log messages starting from this priority (debug, info, warning, error)", cxxopts::value()->default_value("info")); - po::positional_options_description positionalOptionsDescription; - positionalOptionsDescription.add("input", -1); - - po::variables_map variablesMap; + options.parse_positional("input"); + options.positional_help("[]"); const auto printHelp = [&]() { - std::cout - << "Usage: anthem [options] file..." << std::endl - << "Translate ASP programs to the language of first-order theorem provers." << std::endl << std::endl - << description; + std::cout << options.help(); }; + bool help; + bool version; + std::vector inputFiles; + std::string colorPolicyString; + std::string parenthesisStyleString; + std::string logPriorityString; + try { - po::store(po::command_line_parser(argc, argv) - .options(description) - .positional(positionalOptionsDescription) - .run(), - variablesMap); - po::notify(variablesMap); + const auto parseResult = options.parse(argc, argv); + + help = (parseResult.count("help") > 0); + version = (parseResult.count("version") > 0); + + if (parseResult.count("input") > 0) + inputFiles = parseResult["input"].as>(); + + context.performSimplification = (parseResult.count("simplify") > 0); + context.performCompletion = (parseResult.count("complete") > 0); + colorPolicyString = parseResult["color"].as(); + parenthesisStyleString = parseResult["parentheses"].as(); + logPriorityString = parseResult["log-priority"].as(); } - catch (const po::error &e) + catch (const std::exception &exception) { - context.logger.log(anthem::output::Priority::Error) << e.what(); + context.logger.log(anthem::output::Priority::Error) << exception.what(); + context.logger.errorStream() << std::endl; printHelp(); return EXIT_FAILURE; } - if (variablesMap.count("help")) + if (help) { printHelp(); return EXIT_SUCCESS; } - if (variablesMap.count("version")) + if (version) { std::cout << "anthem version 0.1.7-git" << std::endl; return EXIT_SUCCESS; } - const auto colorPolicyString = variablesMap["color"].as(); - if (colorPolicyString == "auto") context.logger.setColorPolicy(anthem::output::ColorStream::ColorPolicy::Auto); else if (colorPolicyString == "never") @@ -81,22 +88,18 @@ int main(int argc, char **argv) return EXIT_FAILURE; } - const auto parenthesisStyle = variablesMap["parentheses"].as(); - - if (parenthesisStyle == "normal") + if (parenthesisStyleString == "normal") context.parenthesisStyle = anthem::ast::ParenthesisStyle::Normal; - else if (parenthesisStyle == "full") + else if (parenthesisStyleString == "full") context.parenthesisStyle = anthem::ast::ParenthesisStyle::Full; else { - context.logger.log(anthem::output::Priority::Error) << "unknown parenthesis style “" << parenthesisStyle << "”"; + context.logger.log(anthem::output::Priority::Error) << "unknown parenthesis style “" << parenthesisStyleString << "”"; context.logger.errorStream() << std::endl; printHelp(); return EXIT_FAILURE; } - const auto logPriorityString = variablesMap["log-priority"].as(); - try { const auto logPriority = anthem::output::priorityFromName(logPriorityString.c_str()); @@ -112,11 +115,8 @@ int main(int argc, char **argv) try { - if (variablesMap.count("input")) - { - const auto &inputFiles = variablesMap["input"].as>(); + if (!inputFiles.empty()) anthem::translate(inputFiles, context); - } else anthem::translate("std::cin", std::cin, context); } diff --git a/lib/cxxopts b/lib/cxxopts new file mode 160000 index 0000000..8893afe --- /dev/null +++ b/lib/cxxopts @@ -0,0 +1 @@ +Subproject commit 8893afe13cc47dd0be4f25b5ae491e652c146098