Add expected_non_option_count to OptionParser.

GitOrigin-RevId: 41bf15d9bddf1673c0c421ef9e5108a5678f9842
This commit is contained in:
levlam 2020-06-19 06:00:01 +03:00
parent 251318d2da
commit 47229e1dab
4 changed files with 18 additions and 13 deletions

View File

@ -4362,15 +4362,9 @@ void main(int argc, char **argv) {
} }
return Status::OK(); return Status::OK();
}); });
auto res = options.run(argc, argv); auto r_non_options = options.run(argc, argv, 0);
if (res.is_error()) { if (r_non_options.is_error()) {
LOG(PLAIN) << "tg_cli: " << res.error().message(); LOG(PLAIN) << argv[0] << ": " << r_non_options.error().message();
LOG(PLAIN) << options;
return;
}
if (!res.ok().empty()) {
LOG(PLAIN) << "tg_cli: "
<< "Have unexpected non-option parameters";
LOG(PLAIN) << options; LOG(PLAIN) << options;
return; return;
} }

View File

@ -51,7 +51,7 @@ void OptionParser::add_check(std::function<Status()> check) {
checks_.push_back(std::move(check)); checks_.push_back(std::move(check));
} }
Result<vector<char *>> OptionParser::run(int argc, char *argv[]) { Result<vector<char *>> OptionParser::run(int argc, char *argv[], int expected_non_option_count) {
std::unordered_map<char, const Option *> short_options; std::unordered_map<char, const Option *> short_options;
std::unordered_map<string, const Option *> long_options; std::unordered_map<string, const Option *> long_options;
for (auto &opt : options_) { for (auto &opt : options_) {
@ -147,6 +147,16 @@ Result<vector<char *>> OptionParser::run(int argc, char *argv[]) {
TRY_STATUS(option->arg_callback(parameter)); TRY_STATUS(option->arg_callback(parameter));
} }
} }
if (expected_non_option_count >= 0 && non_options.size() != static_cast<size_t>(expected_non_option_count)) {
if (expected_non_option_count == 0) {
return Status::Error("Unexpected non-option parameters specified");
}
if (non_options.size() > static_cast<size_t>(expected_non_option_count)) {
return Status::Error("Too much non-option parameters specified");
} else {
return Status::Error("Too few non-option parameters specified");
}
}
for (auto &check : checks_) { for (auto &check : checks_) {
TRY_STATUS(check()); TRY_STATUS(check());
} }

View File

@ -43,7 +43,7 @@ class OptionParser {
void add_check(std::function<Status()> check); void add_check(std::function<Status()> check);
// returns found non-option parameters // returns found non-option parameters
Result<vector<char *>> run(int argc, char *argv[]) TD_WARN_UNUSED_RESULT; Result<vector<char *>> run(int argc, char *argv[], int expected_non_option_count = -1) TD_WARN_UNUSED_RESULT;
friend StringBuilder &operator<<(StringBuilder &sb, const OptionParser &o); friend StringBuilder &operator<<(StringBuilder &sb, const OptionParser &o);

View File

@ -29,8 +29,9 @@ int main(int argc, char **argv) {
options.add_option('\0', "filter", "Run only specified tests", options.add_option('\0', "filter", "Run only specified tests",
[&](td::Slice filter) { runner.add_substr_filter(filter.str()); }); [&](td::Slice filter) { runner.add_substr_filter(filter.str()); });
options.add_option('\0', "stress", "Run tests infinitely", [&] { runner.set_stress_flag(true); }); options.add_option('\0', "stress", "Run tests infinitely", [&] { runner.set_stress_flag(true); });
auto result = options.run(argc, argv); auto r_non_options = options.run(argc, argv, 0);
if (result.is_error() || !result.ok().empty()) { if (r_non_options.is_error()) {
LOG(PLAIN) << argv[0] << ": " << r_non_options.error().message();
LOG(PLAIN) << options; LOG(PLAIN) << options;
return 1; return 1;
} }