diff options
| author | HampusM <hampus@hampusmat.com> | 2022-02-27 12:54:10 +0100 | 
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2022-06-13 17:56:53 +0200 | 
| commit | 5864e5abc43b201c3801fa39a2fcaf9e3a9e8914 (patch) | |
| tree | 98e5e324066ef4d1cbd3cc4c792a258fbd86c12d /src/argument_parser.cpp | |
| parent | e233dc28491c33e8a7dc0a11576d3b8ce91cce2c (diff) | |
refactor: use dependency injection
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; +} | 
