diff --git a/td/telegram/cli.cpp b/td/telegram/cli.cpp index 9bea5f2f0..1e336d7ec 100644 --- a/td/telegram/cli.cpp +++ b/td/telegram/cli.cpp @@ -4330,10 +4330,7 @@ void main(int argc, char **argv) { td::OptionParser options; options.set_description("TDLib test client"); - options.add_option('\0', "test", "Use test DC", [&] { - use_test_dc = true; - return Status::OK(); - }); + options.add_option('\0', "test", "Use test DC", [&] { use_test_dc = true; }); options.add_option('v', "verbosity", "Set verbosity level", [&](Slice level) { int new_verbosity = 1; while (begins_with(level, "v")) { @@ -4344,39 +4341,21 @@ void main(int argc, char **argv) { new_verbosity += to_integer(level) - (new_verbosity == 1); } new_verbosity_level = VERBOSITY_NAME(FATAL) + new_verbosity; - return Status::OK(); }); options.add_option('l', "log", "Log to file", [&](Slice file_name) { if (file_log.init(file_name.str()).is_ok() && file_log.init(file_name.str()).is_ok() && file_log.init(file_name.str(), 1000 << 20).is_ok()) { log_interface = &ts_log; } - return Status::OK(); - }); - options.add_option('W', "", "Preload chat list", [&] { - get_chat_list = true; - return Status::OK(); - }); - options.add_option('n', "disable-network", "Disable network", [&] { - disable_network = true; - return Status::OK(); - }); - options.add_option('\0', "api-id", "Set Telegram API ID", [&](Slice parameter) { - api_id = to_integer(parameter); - return Status::OK(); - }); - options.add_option('\0', "api_id", "Set Telegram API ID", [&](Slice parameter) { - api_id = to_integer(parameter); - return Status::OK(); - }); - options.add_option('\0', "api-hash", "Set Telegram API hash", [&](Slice parameter) { - api_hash = parameter.str(); - return Status::OK(); - }); - options.add_option('\0', "api_hash", "Set Telegram API hash", [&](Slice parameter) { - api_hash = parameter.str(); - return Status::OK(); }); + options.add_option('W', "", "Preload chat list", [&] { get_chat_list = true; }); + options.add_option('n', "disable-network", "Disable network", [&] { disable_network = true; }); + options.add_option('\0', "api-id", "Set Telegram API ID", + [&](Slice parameter) { api_id = to_integer(parameter); }); + options.add_option('\0', "api_id", "Set Telegram API ID", + [&](Slice parameter) { api_id = to_integer(parameter); }); + options.add_option('\0', "api-hash", "Set Telegram API hash", [&](Slice parameter) { api_hash = parameter.str(); }); + options.add_option('\0', "api_hash", "Set Telegram API hash", [&](Slice parameter) { api_hash = parameter.str(); }); auto res = options.run(argc, argv); if (res.is_error()) { LOG(PLAIN) << "tg_cli: " << res.error().message(); diff --git a/tdutils/td/utils/OptionParser.cpp b/tdutils/td/utils/OptionParser.cpp index 034dc993c..77a32c8ba 100644 --- a/tdutils/td/utils/OptionParser.cpp +++ b/tdutils/td/utils/OptionParser.cpp @@ -22,16 +22,29 @@ void OptionParser::add_option(Option::Type type, char short_key, Slice long_key, options_.push_back(Option{type, short_key, long_key.str(), description.str(), std::move(callback)}); } -void OptionParser::add_option(char short_key, Slice long_key, Slice description, - std::function callback) { +void OptionParser::add_checked_option(char short_key, Slice long_key, Slice description, + std::function callback) { add_option(Option::Type::Arg, short_key, long_key, description, std::move(callback)); } -void OptionParser::add_option(char short_key, Slice long_key, Slice description, std::function callback) { - // Ouch. There must be some better way +void OptionParser::add_checked_option(char short_key, Slice long_key, Slice description, + std::function callback) { add_option(Option::Type::NoArg, short_key, long_key, description, - std::bind([](std::function &func, Slice) { return func(); }, std::move(callback), - std::placeholders::_1)); + [callback = std::move(callback)](Slice) { return callback(); }); +} + +void OptionParser::add_option(char short_key, Slice long_key, Slice description, std::function callback) { + add_option(Option::Type::Arg, short_key, long_key, description, [callback = std::move(callback)](Slice parameter) { + callback(parameter); + return Status::OK(); + }); +} + +void OptionParser::add_option(char short_key, Slice long_key, Slice description, std::function callback) { + add_option(Option::Type::NoArg, short_key, long_key, description, [callback = std::move(callback)](Slice) { + callback(); + return Status::OK(); + }); } Result> OptionParser::run(int argc, char *argv[]) { @@ -64,11 +77,11 @@ Result> OptionParser::run(int argc, char *argv[]) { if (arg[1] == '-') { // long option Slice long_arg(arg + 2, std::strlen(arg + 2)); - Slice param; + Slice parameter; auto equal_pos = long_arg.find('='); bool has_equal = equal_pos != Slice::npos; if (has_equal) { - param = long_arg.substr(equal_pos + 1); + parameter = long_arg.substr(equal_pos + 1); long_arg = long_arg.substr(0, equal_pos); } @@ -89,14 +102,14 @@ Result> OptionParser::run(int argc, char *argv[]) { if (++arg_pos == argc) { return Status::Error(PSLICE() << "Option " << long_arg << " must have argument"); } - param = Slice(argv[arg_pos], std::strlen(argv[arg_pos])); + parameter = Slice(argv[arg_pos], std::strlen(argv[arg_pos])); } break; default: UNREACHABLE(); } - TRY_STATUS(option->arg_callback(param)); + TRY_STATUS(option->arg_callback(parameter)); continue; } @@ -107,7 +120,7 @@ Result> OptionParser::run(int argc, char *argv[]) { } auto option = it->second; - Slice param; + Slice parameter; switch (option->type) { case Option::Type::NoArg: // nothing to do @@ -117,17 +130,17 @@ Result> OptionParser::run(int argc, char *argv[]) { if (++arg_pos == argc) { return Status::Error(PSLICE() << "Option " << arg[opt_pos] << " must have argument"); } - param = Slice(argv[arg_pos], std::strlen(argv[arg_pos])); + parameter = Slice(argv[arg_pos], std::strlen(argv[arg_pos])); } else { - param = Slice(arg + opt_pos + 1, std::strlen(arg + opt_pos + 1)); - opt_pos += param.size(); + parameter = Slice(arg + opt_pos + 1, std::strlen(arg + opt_pos + 1)); + opt_pos += parameter.size(); } break; default: UNREACHABLE(); } - TRY_STATUS(option->arg_callback(param)); + TRY_STATUS(option->arg_callback(parameter)); } } diff --git a/tdutils/td/utils/OptionParser.h b/tdutils/td/utils/OptionParser.h index ecc520090..3ddabf232 100644 --- a/tdutils/td/utils/OptionParser.h +++ b/tdutils/td/utils/OptionParser.h @@ -32,9 +32,13 @@ class OptionParser { public: void set_description(string description); - void add_option(char short_key, Slice long_key, Slice description, std::function callback); + void add_checked_option(char short_key, Slice long_key, Slice description, std::function callback); - void add_option(char short_key, Slice long_key, Slice description, std::function callback); + void add_checked_option(char short_key, Slice long_key, Slice description, std::function callback); + + void add_option(char short_key, Slice long_key, Slice description, std::function callback); + + void add_option(char short_key, Slice long_key, Slice description, std::function callback); // returns found non-option parameters Result> run(int argc, char *argv[]) TD_WARN_UNUSED_RESULT; diff --git a/test/main.cpp b/test/main.cpp index 81a22b0e7..9e93f4fcd 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -26,14 +26,9 @@ int main(int argc, char **argv) { SET_VERBOSITY_LEVEL(VERBOSITY_NAME(ERROR)); td::OptionParser options; - options.add_option('\0', "filter", "Run only specified tests", [&](td::Slice filter) { - runner.add_substr_filter(filter.str()); - return td::Status::OK(); - }); - options.add_option('\0', "stress", "Run tests infinitely", [&] { - runner.set_stress_flag(true); - return td::Status::OK(); - }); + options.add_option('\0', "filter", "Run only specified tests", + [&](td::Slice filter) { runner.add_substr_filter(filter.str()); }); + options.add_option('\0', "stress", "Run tests infinitely", [&] { runner.set_stress_flag(true); }); auto result = options.run(argc, argv); if (result.is_error() || !result.ok().empty()) { LOG(PLAIN) << options;