aboutsummaryrefslogtreecommitdiff
path: root/src/argument_parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/argument_parser.cpp')
-rw-r--r--src/argument_parser.cpp100
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;
+}