feat: parser settings.

This commit is contained in:
2026-05-13 13:05:51 +04:00
parent 8a57dca32e
commit 3f63bf958f
4 changed files with 42 additions and 18 deletions

View File

@@ -1,4 +1,5 @@
#include "argument_parser.hpp" #include "argument_parser.hpp"
#include "exceptions.hpp"
#include <algorithm> #include <algorithm>
#include <functional> #include <functional>
@@ -6,6 +7,7 @@
#include <iostream> #include <iostream>
#include <optional> #include <optional>
#include <sstream> #include <sstream>
#include <stdexcept>
#include <string> #include <string>
#include <thread> #include <thread>
#include <unordered_map> #include <unordered_map>
@@ -28,8 +30,7 @@ bool contains(std::unordered_map<std::string, int> const &map, std::string const
} }
namespace argument_parser { namespace argument_parser {
argument::argument() argument::argument() : id(0), action(std::make_unique<action_no_param>([] {})), required(false), invoked(false) {}
: id(0), action(std::make_unique<non_parametered_action>([] {})), required(false), invoked(false) {}
argument::argument(const argument &other) argument::argument(const argument &other)
: id(other.id), name(other.name), action(other.action->clone()), required(other.required), : id(other.id), name(other.name), action(other.action->clone()), required(other.required),
@@ -331,8 +332,11 @@ namespace argument_parser {
next_positional_index = *slot + 1; next_positional_index = *slot + 1;
} }
} else { } else {
throw std::runtime_error("All trials for argument: \n\t\"" + *it + "\"\n failed with: \n" + if (m_settings.ignore_unknown_arguments) {
error_stream.str()); continue;
}
throw parser::unknown_argument_exception("All trials for argument: \n\t\"" + *it +
"\"\n failed with: \n" + error_stream.str());
} }
} }
} }
@@ -389,8 +393,21 @@ namespace argument_parser {
std::vector<found_argument> found_arguments; std::vector<found_argument> found_arguments;
std::optional<argument> found_help = std::nullopt; std::optional<argument> found_help = std::nullopt;
try {
extract_arguments(convention_types, found_arguments, found_help); extract_arguments(convention_types, found_arguments, found_help);
invoke_arguments(found_arguments, found_help); invoke_arguments(found_arguments, found_help);
} catch (parser::unknown_argument_exception const &e) {
if (m_settings.should_exit_on_unknown_argument) {
std::exit(1);
}
throw e;
} catch (std::exception const &e) {
if (m_settings.should_exit_on_error) {
std::exit(1);
}
throw e;
}
check_for_required_arguments(convention_types); check_for_required_arguments(convention_types);
fire_on_complete_events(); fire_on_complete_events();
} }
@@ -588,8 +605,11 @@ namespace argument_parser {
} }
std::cerr << "\n"; std::cerr << "\n";
display_help(convention_types); display_help(convention_types);
if (m_settings.should_exit_on_missing_required) {
std::exit(1); std::exit(1);
} }
throw std::runtime_error("required arguments not provided");
}
} }
void base_parser::fire_on_complete_events() const { void base_parser::fire_on_complete_events() const {

View File

@@ -15,7 +15,7 @@ namespace argument_parser {
} }
namespace v2 { namespace v2 {
linux_parser::linux_parser(bool should_exit) { linux_parser::linux_parser(parser_settings const &settings) {
std::ifstream command_line_file{"/proc/self/cmdline"}; std::ifstream command_line_file{"/proc/self/cmdline"};
std::string program_name; std::string program_name;
std::getline(command_line_file, program_name, '\0'); std::getline(command_line_file, program_name, '\0');
@@ -25,7 +25,7 @@ namespace argument_parser {
ref_parsed_args().emplace_back(line); ref_parsed_args().emplace_back(line);
} }
prepare_help_flag(should_exit); prepare_help_flag(settings.should_exit_on_help);
} }
} // namespace v2 } // namespace v2
} // namespace argument_parser } // namespace argument_parser

View File

@@ -7,12 +7,15 @@
#define MACOS_GETARGS_LOOP(argc_name, argv_name, before_for, for_body) \ #define MACOS_GETARGS_LOOP(argc_name, argv_name, before_for, for_body) \
do { \ do { \
const int(argc_name) = *_NSGetArgc(); \ const int(argc_name) = *_NSGetArgc(); \
if (char **(argv_name) = *_NSGetArgv(); (argc_name) > 0 && (argv_name) != nullptr && (argv_name)[0] != nullptr) { \ if (char **(argv_name) = *_NSGetArgv(); \
(argc_name) > 0 && (argv_name) != nullptr && (argv_name)[0] != nullptr) { \
do { \ do { \
(before_for); \ (before_for); \
} while (false); \ } while (false); \
for (int i = 1; i < (argc_name); ++i) { \ for (int i = 1; i < (argc_name); ++i) { \
{for_body} \ { \
for_body \
} \
} \ } \
} \ } \
} while (false) } while (false)
@@ -26,12 +29,13 @@ namespace argument_parser {
} }
namespace v2 { namespace v2 {
macos_parser::macos_parser(const bool should_exit) { macos_parser::macos_parser(parser_settings const &settings) {
MACOS_GETARGS_LOOP(argc, argv, set_program_name(argv[0]), { MACOS_GETARGS_LOOP(argc, argv, set_program_name(argv[0]), {
if (argv[i] != nullptr) if (argv[i] != nullptr)
ref_parsed_args().emplace_back(argv[i]); ref_parsed_args().emplace_back(argv[i]);
}); });
prepare_help_flag(should_exit); prepare_help_flag(settings.should_exit_on_help);
set_settings(settings);
} }
} // namespace v2 } // namespace v2
} // namespace argument_parser } // namespace argument_parser

View File

@@ -95,11 +95,11 @@ namespace argument_parser {
} // namespace argument_parser } // namespace argument_parser
namespace argument_parser::v2 { namespace argument_parser::v2 {
windows_parser::windows_parser(bool should_exit) { windows_parser::windows_parser(parser_settings const &settings) {
parse_windows_arguments(ref_parsed_args(), parse_windows_arguments(ref_parsed_args(),
[this](std::string const &program_name) { this->set_program_name(program_name); }); [this](std::string const &program_name) { this->set_program_name(program_name); });
prepare_help_flag(should_exit); prepare_help_flag(settings.should_exit_on_help);
} }
} // namespace argument_parser::v2 } // namespace argument_parser::v2