Simplify support for unchecked options in OptionParser.

GitOrigin-RevId: 5a913944b5a6cfecdfb96287e2c670be8ca18547
This commit is contained in:
levlam 2020-06-19 04:44:38 +03:00
parent 0877d7f716
commit 5aa609535e
4 changed files with 46 additions and 55 deletions

View File

@ -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<int>(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<int32>(parameter);
return Status::OK();
});
options.add_option('\0', "api_id", "Set Telegram API ID", [&](Slice parameter) {
api_id = to_integer<int32>(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<int32>(parameter); });
options.add_option('\0', "api_id", "Set Telegram API ID",
[&](Slice parameter) { api_id = to_integer<int32>(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();

View File

@ -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<Status(Slice)> callback) {
void OptionParser::add_checked_option(char short_key, Slice long_key, Slice description,
std::function<Status(Slice)> 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<Status(void)> callback) {
// Ouch. There must be some better way
void OptionParser::add_checked_option(char short_key, Slice long_key, Slice description,
std::function<Status(void)> callback) {
add_option(Option::Type::NoArg, short_key, long_key, description,
std::bind([](std::function<Status(void)> &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<void(Slice)> 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<void(void)> callback) {
add_option(Option::Type::NoArg, short_key, long_key, description, [callback = std::move(callback)](Slice) {
callback();
return Status::OK();
});
}
Result<vector<char *>> OptionParser::run(int argc, char *argv[]) {
@ -64,11 +77,11 @@ Result<vector<char *>> 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<vector<char *>> 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<vector<char *>> 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<vector<char *>> 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));
}
}

View File

@ -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<Status(Slice)> callback);
void add_checked_option(char short_key, Slice long_key, Slice description, std::function<Status(Slice)> callback);
void add_option(char short_key, Slice long_key, Slice description, std::function<Status(void)> callback);
void add_checked_option(char short_key, Slice long_key, Slice description, std::function<Status(void)> callback);
void add_option(char short_key, Slice long_key, Slice description, std::function<void(Slice)> callback);
void add_option(char short_key, Slice long_key, Slice description, std::function<void(void)> callback);
// returns found non-option parameters
Result<vector<char *>> run(int argc, char *argv[]) TD_WARN_UNUSED_RESULT;

View File

@ -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;