diff options
Diffstat (limited to 'src/argument_parser.cpp')
-rw-r--r-- | src/argument_parser.cpp | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/src/argument_parser.cpp b/src/argument_parser.cpp new file mode 100644 index 0000000..b5f14bc --- /dev/null +++ b/src/argument_parser.cpp @@ -0,0 +1,100 @@ +#include "argument_parser.hpp" + +#include "conversion.hpp" +#include "interfaces/randomization.hpp" + +#include <cstdlib> +#include <iostream> +#include <string_view> + +namespace +{ +void optarg_error(char arg, const std::string_view &error) +{ + std::cout << "Error: Invalid option argument for -" << arg << ". " << error + << std::endl; + exit(EXIT_FAILURE); +} + +/** + * Returns the current optarg as a string view. + */ +std::string_view get_str_optarg() +{ + return std::string_view(optarg); +} + +/** + * Returns the current optarg as a unsigned integer. + * + * @param arg The current command-line argument character + * @param check_zero Whether or not to make sure that the result is not zero + */ +unsigned int get_uint_optarg(char arg, bool check_zero = false) +{ + auto conversion_result = str_to_uint(get_str_optarg()); + + if (!conversion_result.success || (check_zero && conversion_result.result == 0)) + { + optarg_error(arg, conversion_result.fail_reason); + } + + return conversion_result.result; +} +} // namespace + +ArgumentParser::ArgumentParser( + IRandomNumberGeneratorFactory random_number_generator_factory) + : _random_number_generator_factory(std::move(random_number_generator_factory)) +{ +} + +ParsedArguments +ArgumentParser::parse(const std::vector<option> &options, + const std::string_view &short_options, const int &argc, + char *const *argv) // NOLINT(cppcoreguidelines-avoid-c-arrays, + // modernize-avoid-c-arrays) +{ + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + const auto args = std::vector<std::string_view>(argv, argv + argc); + + const auto program_name = args[0]; + + ParsedArguments parsed_arguments; + + char arg = 0; + while ((arg = static_cast<char>(getopt_long(argc, argv, short_options.data(), + options.data(), nullptr))) != -1) + { + switch (arg) + { + case 's': + { + auto seed = get_uint_optarg(arg, true); + + parsed_arguments.random_gen = _random_number_generator_factory(seed); + break; + } + case 'h': + { + std::cout << "Usage: " << program_name + << " [OPTION]...\n\n" + "Options:\n" + << " -s, --seed SEED The randomization seed used\n" + " -h --help Displays usage information" + << std::endl; + exit(EXIT_SUCCESS); + } + case '?': + { + std::cout << "\nTry '" << program_name << " --help' for more information" + << std::endl; + exit(EXIT_FAILURE); + } + default: + abort(); + } + } + + return parsed_arguments; +} |