From 23f34b59e3a63f96244612247c5f73c131e3d2a2 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Sun, 27 Mar 2022 11:15:35 +0200 Subject: [PATCH] CLI parser: support for parsing certain options first --- src/common/cli_parser.cpp | 23 +++++++++++++++++++++-- src/common/cli_parser.h | 4 ++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/common/cli_parser.cpp b/src/common/cli_parser.cpp index 950ec6fa9..303ff75c0 100644 --- a/src/common/cli_parser.cpp +++ b/src/common/cli_parser.cpp @@ -95,6 +95,12 @@ parser_c::parse_args() { run_hooks(parser_c::ht_common_options_parsed); + parse_args_pass(true); + parse_args_pass(false); +} + +void +parser_c::parse_args_pass(bool first_pass) { for (auto sit = m_args.cbegin(), sit_end = m_args.cend(); sit != sit_end; sit++) { auto sit_next = sit + 1; auto no_next_arg = sit_next == sit_end; @@ -111,9 +117,11 @@ parser_c::parse_args() { ++sit; } - option.m_callback(); + if ( ( first_pass && m_parse_first[m_current_arg]) + || (!first_pass && !m_parse_first[m_current_arg])) + option.m_callback(); - } else if (!run_hooks(parser_c::ht_unknown_option)) + } else if (!first_pass && !run_hooks(parser_c::ht_unknown_option)) mxerror(fmt::format(Y("Unknown option '{0}'.\n"), m_current_arg)); } } @@ -197,6 +205,17 @@ parser_c::set_usage() { mtx::cli::g_usage_text += option.format_text(); } +void +parser_c::set_to_parse_first(std::vector const &names) { + for (auto const &name : names) + m_parse_first[name] = true; +} + +void +parser_c::set_to_parse_first(std::string const &name) { + m_parse_first[name] = true; +} + void parser_c::dummy_callback() { } diff --git a/src/common/cli_parser.h b/src/common/cli_parser.h index cf18c38f1..838ef4893 100644 --- a/src/common/cli_parser.h +++ b/src/common/cli_parser.h @@ -53,6 +53,7 @@ protected: std::map m_option_map; std::vector m_options; std::vector m_args; + std::unordered_map m_parse_first; std::string m_current_arg, m_next_arg; @@ -71,7 +72,10 @@ protected: void add_common_options(); void parse_args(); + void parse_args_pass(bool first_pass); void set_usage(); + void set_to_parse_first(std::vector const &names); + void set_to_parse_first(std::string const &name); void dummy_callback();