diff --git a/tools/utils.hh b/tools/utils.hh index 907d29b062..e6fb73b86e 100644 --- a/tools/utils.hh +++ b/tools/utils.hh @@ -35,6 +35,39 @@ concept Operation = requires(Op op) { { op.name() }; // returns some string }; +// Extract the operation from the argv. +// +// The operation is expected to be at argv[1].If found, it is shifted out to the +// end (effectively removed) and the corresponding Op* is returned. +// If not found or unrecognized an error is logged and exit() is called. +template +const Op& get_selected_operation(int& ac, char**& av, const std::vector& operations, std::string_view alias) { + if (ac < 2) { + fmt::print(std::cerr, "error: missing mandatory {} argument\n", alias); + exit(1); + } + + const Op* found_operation = nullptr; + for (const auto& op : operations) { + if (av[1] == op.name()) { + found_operation = &op; + break; + } + } + if (found_operation) { + --ac; + for (int i = 1; i < ac; ++i) { + std::swap(av[i], av[i + 1]); + } + return *found_operation; + } + + const auto all_operation_names = boost::algorithm::join(operations | boost::adaptors::transformed([] (const Op& op) { return op.name(); } ), ", "); + + fmt::print(std::cerr, "error: unrecognized {} argument: expected one of ({}), got {}\n", alias, all_operation_names, av[1]); + exit(1); +} + template const Op& get_selected_operation(boost::program_options::variables_map& app_config, const std::vector& operations, std::string_view alias) { std::vector found_operations;