From 3f63bf958f5023ba5c26232b9ad1bf215be0bfd8 Mon Sep 17 00:00:00 2001 From: "killua.z" Date: Wed, 13 May 2026 13:05:51 +0400 Subject: [PATCH] feat: parser settings. --- src/source/parser/argument_parser.cpp | 34 +++++++++++++++---- .../parser/platform_parsers/linux_parser.cpp | 4 +-- .../parser/platform_parsers/macos_parser.cpp | 18 ++++++---- .../platform_parsers/windows_parser.cpp | 4 +-- 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/source/parser/argument_parser.cpp b/src/source/parser/argument_parser.cpp index 9c7ecb0..e7c2f26 100644 --- a/src/source/parser/argument_parser.cpp +++ b/src/source/parser/argument_parser.cpp @@ -1,4 +1,5 @@ #include "argument_parser.hpp" +#include "exceptions.hpp" #include #include @@ -6,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -28,8 +30,7 @@ bool contains(std::unordered_map const &map, std::string const } namespace argument_parser { - argument::argument() - : id(0), action(std::make_unique([] {})), required(false), invoked(false) {} + argument::argument() : id(0), action(std::make_unique([] {})), required(false), invoked(false) {} argument::argument(const argument &other) : 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; } } else { - throw std::runtime_error("All trials for argument: \n\t\"" + *it + "\"\n failed with: \n" + - error_stream.str()); + if (m_settings.ignore_unknown_arguments) { + 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_arguments; std::optional found_help = std::nullopt; - extract_arguments(convention_types, found_arguments, found_help); - invoke_arguments(found_arguments, found_help); + try { + extract_arguments(convention_types, 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); fire_on_complete_events(); } @@ -588,7 +605,10 @@ namespace argument_parser { } std::cerr << "\n"; display_help(convention_types); - std::exit(1); + if (m_settings.should_exit_on_missing_required) { + std::exit(1); + } + throw std::runtime_error("required arguments not provided"); } } diff --git a/src/source/parser/platform_parsers/linux_parser.cpp b/src/source/parser/platform_parsers/linux_parser.cpp index be9dc2b..26616fc 100644 --- a/src/source/parser/platform_parsers/linux_parser.cpp +++ b/src/source/parser/platform_parsers/linux_parser.cpp @@ -15,7 +15,7 @@ namespace argument_parser { } 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::string program_name; std::getline(command_line_file, program_name, '\0'); @@ -25,7 +25,7 @@ namespace argument_parser { ref_parsed_args().emplace_back(line); } - prepare_help_flag(should_exit); + prepare_help_flag(settings.should_exit_on_help); } } // namespace v2 } // namespace argument_parser diff --git a/src/source/parser/platform_parsers/macos_parser.cpp b/src/source/parser/platform_parsers/macos_parser.cpp index 7a219c9..82c5565 100644 --- a/src/source/parser/platform_parsers/macos_parser.cpp +++ b/src/source/parser/platform_parsers/macos_parser.cpp @@ -6,13 +6,16 @@ #define MACOS_GETARGS_LOOP(argc_name, argv_name, before_for, for_body) \ do { \ - const int (argc_name) = *_NSGetArgc(); \ - if (char **(argv_name) = *_NSGetArgv(); (argc_name) > 0 && (argv_name) != nullptr && (argv_name)[0] != nullptr) { \ + const int(argc_name) = *_NSGetArgc(); \ + if (char **(argv_name) = *_NSGetArgv(); \ + (argc_name) > 0 && (argv_name) != nullptr && (argv_name)[0] != nullptr) { \ do { \ - (before_for); \ + (before_for); \ } while (false); \ - for (int i = 1; i < (argc_name); ++i) { \ - {for_body} \ + for (int i = 1; i < (argc_name); ++i) { \ + { \ + for_body \ + } \ } \ } \ } while (false) @@ -26,12 +29,13 @@ namespace argument_parser { } 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]), { if (argv[i] != nullptr) 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 argument_parser diff --git a/src/source/parser/platform_parsers/windows_parser.cpp b/src/source/parser/platform_parsers/windows_parser.cpp index 45c7d36..b2dd360 100644 --- a/src/source/parser/platform_parsers/windows_parser.cpp +++ b/src/source/parser/platform_parsers/windows_parser.cpp @@ -95,11 +95,11 @@ namespace argument_parser { } // namespace argument_parser 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(), [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