123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- #include "last_getopt_parse_result.h"
- namespace NLastGetopt {
- const TOptParseResult* TOptsParseResult::FindParseResult(const TdVec& vec, const TOpt* opt) {
- for (const auto& r : vec) {
- if (r.OptPtr() == opt)
- return &r;
- }
- return nullptr;
- }
- const TOptParseResult* TOptsParseResult::FindOptParseResult(const TOpt* opt, bool includeDefault) const {
- const TOptParseResult* r = FindParseResult(Opts_, opt);
- if (nullptr == r && includeDefault)
- r = FindParseResult(OptsDef_, opt);
- return r;
- }
- const TOptParseResult* TOptsParseResult::FindLongOptParseResult(const TString& name, bool includeDefault) const {
- return FindOptParseResult(&Parser_->Opts_->GetLongOption(name), includeDefault);
- }
- const TOptParseResult* TOptsParseResult::FindCharOptParseResult(char c, bool includeDefault) const {
- return FindOptParseResult(&Parser_->Opts_->GetCharOption(c), includeDefault);
- }
- bool TOptsParseResult::Has(const TOpt* opt, bool includeDefault) const {
- Y_ASSERT(opt);
- return FindOptParseResult(opt, includeDefault) != nullptr;
- }
- bool TOptsParseResult::Has(const TString& name, bool includeDefault) const {
- return FindLongOptParseResult(name, includeDefault) != nullptr;
- }
- bool TOptsParseResult::Has(char c, bool includeDefault) const {
- return FindCharOptParseResult(c, includeDefault) != nullptr;
- }
- const char* TOptsParseResult::Get(const TOpt* opt, bool includeDefault) const {
- Y_ASSERT(opt);
- const TOptParseResult* r = FindOptParseResult(opt, includeDefault);
- if (!r || r->Empty()) {
- try {
- throw TUsageException() << "option " << opt->ToShortString() << " is unspecified";
- } catch (...) {
- HandleError();
- // unreachable
- throw;
- }
- } else {
- return r->Back();
- }
- }
- const char* TOptsParseResult::GetOrElse(const TOpt* opt, const char* defaultValue) const {
- Y_ASSERT(opt);
- const TOptParseResult* r = FindOptParseResult(opt);
- if (!r || r->Empty()) {
- return defaultValue;
- } else {
- return r->Back();
- }
- }
- const char* TOptsParseResult::Get(const TString& name, bool includeDefault) const {
- return Get(&Parser_->Opts_->GetLongOption(name), includeDefault);
- }
- const char* TOptsParseResult::Get(char c, bool includeDefault) const {
- return Get(&Parser_->Opts_->GetCharOption(c), includeDefault);
- }
- const char* TOptsParseResult::GetOrElse(const TString& name, const char* defaultValue) const {
- if (!Has(name))
- return defaultValue;
- return Get(name);
- }
- const char* TOptsParseResult::GetOrElse(char c, const char* defaultValue) const {
- if (!Has(c))
- return defaultValue;
- return Get(c);
- }
- TOptParseResult& TOptsParseResult::OptParseResult() {
- const TOpt* opt = Parser_->CurOpt();
- Y_ASSERT(opt);
- TdVec& opts = Parser_->IsExplicit() ? Opts_ : OptsDef_;
- if (Parser_->IsExplicit()) // default options won't appear twice
- for (auto& it : opts)
- if (it.OptPtr() == opt)
- return it;
- opts.push_back(TOptParseResult(opt));
- return opts.back();
- }
- TString TOptsParseResult::GetProgramName() const {
- return Parser_->ProgramName_;
- }
- void TOptsParseResult::PrintUsage(IOutputStream& os) const {
- Parser_->Opts_->PrintUsage(Parser_->ProgramName_, os);
- }
- size_t TOptsParseResult::GetFreeArgsPos() const {
- return Parser_->Pos_;
- }
- TVector<TString> TOptsParseResult::GetFreeArgs() const {
- TVector<TString> v;
- for (size_t i = GetFreeArgsPos(); i < Parser_->Argc_; ++i) {
- v.push_back(Parser_->Argv_[i]);
- }
- return v;
- }
- size_t TOptsParseResult::GetFreeArgCount() const {
- return Parser_->Argc_ - GetFreeArgsPos();
- }
- void FindUserTypos(const TString& arg, const TOpts* options) {
- if (arg.size() < 4 || !arg.StartsWith("-")) {
- return;
- }
- for (auto opt: options->Opts_) {
- for (auto name: opt->GetLongNames()) {
- if ("-" + name == arg) {
- throw TUsageException() << "did you mean `-" << arg << "` (with two dashes)?";
- }
- }
- }
- }
- void TOptsParseResult::Init(const TOpts* options, int argc, const char** argv) {
- try {
- Parser_.Reset(new TOptsParser(options, argc, argv));
- while (Parser_->Next()) {
- TOptParseResult& r = OptParseResult();
- r.AddValue(Parser_->CurValOrOpt().data());
- }
- Y_ENSURE(options);
- const auto freeArgs = GetFreeArgs();
- for (size_t i = 0; i < freeArgs.size(); ++i) {
- if (i >= options->ArgBindings_.size()) {
- break;
- }
- options->ArgBindings_[i](freeArgs[i]);
- }
- if (options->CheckUserTypos_) {
- for (auto arg: TVector<TString>(argv, std::next(argv, argc))) {
- FindUserTypos(arg, options);
- }
- }
- } catch (...) {
- HandleError();
- }
- }
- void TOptsParseResult::HandleError() const {
- Cerr << CurrentExceptionMessage() << Endl;
- if (Parser_.Get()) { // parser initializing can fail (and we get here, see Init)
- if (Parser_->Opts_->FindLongOption("help") != nullptr) {
- Cerr << "Try '" << Parser_->ProgramName_ << " --help' for more information." << Endl;
- } else {
- PrintUsage();
- }
- }
- exit(1);
- }
- void TOptsParseResultException::HandleError() const {
- throw;
- }
- }
|