aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/getopt/small/last_getopt_parser.cpp
diff options
context:
space:
mode:
authorIlnur Khuziev <ilnur.khuziev@yandex.ru>2022-02-10 16:46:13 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:46:13 +0300
commit736dcd8ca259457a136f2f9f9168c44643914323 (patch)
treeddd46a036d68bfa83aa11b892f31243ea6b068a1 /library/cpp/getopt/small/last_getopt_parser.cpp
parent9bf2fa2b060c9881d3135c2208c624a1dd546ecc (diff)
downloadydb-736dcd8ca259457a136f2f9f9168c44643914323.tar.gz
Restoring authorship annotation for Ilnur Khuziev <ilnur.khuziev@yandex.ru>. Commit 1 of 2.
Diffstat (limited to 'library/cpp/getopt/small/last_getopt_parser.cpp')
-rw-r--r--library/cpp/getopt/small/last_getopt_parser.cpp162
1 files changed, 81 insertions, 81 deletions
diff --git a/library/cpp/getopt/small/last_getopt_parser.cpp b/library/cpp/getopt/small/last_getopt_parser.cpp
index 7668b12a03..7c474809ce 100644
--- a/library/cpp/getopt/small/last_getopt_parser.cpp
+++ b/library/cpp/getopt/small/last_getopt_parser.cpp
@@ -1,23 +1,23 @@
-#include "last_getopt_parser.h"
-
+#include "last_getopt_parser.h"
+
#include <library/cpp/colorizer/colors.h>
-#include <util/string/escape.h>
-
-namespace NLastGetopt {
+#include <util/string/escape.h>
+
+namespace NLastGetopt {
void TOptsParser::Init(const TOpts* opts, int argc, const char* argv[]) {
opts->Validate();
-
+
Opts_ = opts;
-
+
if (argc < 1)
throw TUsageException() << "argv must have at least one argument";
-
+
Argc_ = argc;
Argv_ = argv;
-
+
ProgramName_ = argv[0];
-
+
Pos_ = 1;
Sop_ = 0;
CurrentOpt_ = nullptr;
@@ -27,11 +27,11 @@ namespace NLastGetopt {
OptsSeen_.clear();
OptsDefault_.clear();
}
-
+
void TOptsParser::Init(const TOpts* opts, int argc, char* argv[]) {
Init(opts, argc, const_cast<const char**>(argv));
}
-
+
void TOptsParser::Swap(TOptsParser& that) {
DoSwap(Opts_, that.Opts_);
DoSwap(Argc_, that.Argc_);
@@ -46,7 +46,7 @@ namespace NLastGetopt {
DoSwap(GotMinusMinus_, that.GotMinusMinus_);
DoSwap(OptsSeen_, that.OptsSeen_);
}
-
+
bool TOptsParser::Commit(const TOpt* currentOpt, const TStringBuf& currentValue, size_t pos, size_t sop) {
Pos_ = pos;
Sop_ = sop;
@@ -56,62 +56,62 @@ namespace NLastGetopt {
OptsSeen_.insert(currentOpt);
return true;
}
-
+
bool TOptsParser::CommitEndOfOptions(size_t pos) {
Pos_ = pos;
Sop_ = 0;
Y_ASSERT(!CurOpt());
Y_ASSERT(!CurVal());
-
+
Y_ASSERT(!Stopped_);
-
+
if (Opts_->FreeArgsMin_ == Opts_->FreeArgsMax_ && Argc_ - Pos_ != Opts_->FreeArgsMin_)
throw TUsageException() << "required exactly " << Opts_->FreeArgsMin_ << " free args";
else if (Argc_ - Pos_ < Opts_->FreeArgsMin_)
throw TUsageException() << "required at least " << Opts_->FreeArgsMin_ << " free args";
else if (Argc_ - Pos_ > Opts_->FreeArgsMax_)
throw TUsageException() << "required at most " << Opts_->FreeArgsMax_ << " free args";
-
+
return false;
}
-
+
bool TOptsParser::ParseUnknownShortOptWithinArg(size_t pos, size_t sop) {
Y_ASSERT(pos < Argc_);
const TStringBuf arg(Argv_[pos]);
Y_ASSERT(sop > 0);
Y_ASSERT(sop < arg.length());
Y_ASSERT(EIO_NONE != IsOpt(arg));
-
+
if (!Opts_->AllowUnknownCharOptions_)
throw TUsageException() << "unknown option '" << EscapeC(arg[sop])
<< "' in '" << arg << "'";
-
+
TempCurrentOpt_.Reset(new TOpt);
TempCurrentOpt_->AddShortName(arg[sop]);
-
+
sop += 1;
-
+
// mimic behavior of Opt: unknown option has arg only if char is last within arg
if (sop < arg.length()) {
return Commit(TempCurrentOpt_.Get(), nullptr, pos, sop);
}
-
+
pos += 1;
sop = 0;
if (pos == Argc_ || EIO_NONE != IsOpt(Argv_[pos])) {
return Commit(TempCurrentOpt_.Get(), nullptr, pos, 0);
}
-
+
return Commit(TempCurrentOpt_.Get(), Argv_[pos], pos + 1, 0);
- }
-
+ }
+
bool TOptsParser::ParseShortOptWithinArg(size_t pos, size_t sop) {
Y_ASSERT(pos < Argc_);
const TStringBuf arg(Argv_[pos]);
Y_ASSERT(sop > 0);
Y_ASSERT(sop < arg.length());
Y_ASSERT(EIO_NONE != IsOpt(arg));
-
+
size_t p = sop;
char c = arg[p];
const TOpt* opt = Opts_->FindCharOption(c);
@@ -126,15 +126,15 @@ namespace NLastGetopt {
}
return Commit(opt, arg.SubStr(p), pos + 1, 0);
}
-
+
bool TOptsParser::ParseShortOptArg(size_t pos) {
Y_ASSERT(pos < Argc_);
const TStringBuf arg(Argv_[pos]);
Y_ASSERT(EIO_NONE != IsOpt(arg));
Y_ASSERT(!arg.StartsWith("--"));
return ParseShortOptWithinArg(pos, 1);
- }
-
+ }
+
bool TOptsParser::ParseOptArg(size_t pos) {
Y_ASSERT(pos < Argc_);
TStringBuf arg(Argv_[pos]);
@@ -155,7 +155,7 @@ namespace NLastGetopt {
throw TUsageException() << "unknown option '" << optionName
<< "' in '" << Argv_[pos] << "'";
}
- }
+ }
if (arg.IsInited()) {
if (option->GetHasArg() == NO_ARGUMENT)
throw TUsageException() << "option " << optionName << " must have no arg";
@@ -165,9 +165,9 @@ namespace NLastGetopt {
return ParseOptParam(option, pos);
} else {
return ParseShortOptArg(pos);
- }
- }
-
+ }
+ }
+
bool TOptsParser::ParseOptParam(const TOpt* opt, size_t pos) {
Y_ASSERT(opt);
if (opt->GetHasArg() == NO_ARGUMENT) {
@@ -183,8 +183,8 @@ namespace NLastGetopt {
return Commit(opt, arg, pos + 1, 0);
}
return Commit(opt, nullptr, pos, 0);
- }
-
+ }
+
TOptsParser::EIsOpt TOptsParser::IsOpt(const TStringBuf& arg) const {
EIsOpt eio = EIO_NONE;
if (1 < arg.length()) {
@@ -202,35 +202,35 @@ namespace NLastGetopt {
eio = EIO_PLUS;
break;
}
- }
+ }
return eio;
- }
-
+ }
+
static void memrotate(void* ptr, size_t size, size_t shift) {
TTempBuf buf(shift);
memcpy(buf.Data(), (char*)ptr + size - shift, shift);
memmove((char*)ptr + shift, ptr, size - shift);
memcpy(ptr, buf.Data(), shift);
}
-
+
bool TOptsParser::ParseWithPermutation() {
Y_ASSERT(Sop_ == 0);
Y_ASSERT(Opts_->ArgPermutation_ == PERMUTE);
-
+
const size_t p0 = Pos_;
-
+
size_t pc = Pos_;
-
+
for (; pc < Argc_ && EIO_NONE == IsOpt(Argv_[pc]); ++pc) {
// count non-args
}
-
+
if (pc == Argc_) {
return CommitEndOfOptions(Pos_);
}
-
+
Pos_ = pc;
-
+
bool r = ParseOptArg(Pos_);
Y_ASSERT(r);
while (Pos_ == pc) {
@@ -238,33 +238,33 @@ namespace NLastGetopt {
r = ParseShortOptWithinArg(Pos_, Sop_);
Y_ASSERT(r);
}
-
+
size_t p2 = Pos_;
-
+
Y_ASSERT(p2 - pc >= 1);
Y_ASSERT(p2 - pc <= 2);
-
+
memrotate(Argv_ + p0, (p2 - p0) * sizeof(void*), (p2 - pc) * sizeof(void*));
-
+
bool r2 = ParseOptArg(p0);
Y_ASSERT(r2);
return r2;
}
-
+
bool TOptsParser::DoNext() {
Y_ASSERT(Pos_ <= Argc_);
-
+
if (Pos_ == Argc_)
return CommitEndOfOptions(Pos_);
-
+
if (GotMinusMinus_ && Opts_->ArgPermutation_ == RETURN_IN_ORDER) {
Y_ASSERT(Sop_ == 0);
return Commit(nullptr, Argv_[Pos_], Pos_ + 1, 0);
}
-
+
if (Sop_ > 0)
return ParseShortOptWithinArg(Pos_, Sop_);
-
+
size_t pos = Pos_;
const TStringBuf arg(Argv_[pos]);
if (EIO_NONE != IsOpt(arg)) {
@@ -283,59 +283,59 @@ namespace NLastGetopt {
return Commit(nullptr, arg, pos + 1, 0);
} else if (Opts_->ArgPermutation_ == REQUIRE_ORDER) {
return CommitEndOfOptions(Pos_);
- } else {
+ } else {
return ParseWithPermutation();
- }
- }
-
+ }
+ }
+
bool TOptsParser::Next() {
bool r = false;
-
+
if (OptsDefault_.empty()) {
CurrentOpt_ = nullptr;
TempCurrentOpt_.Destroy();
-
+
CurrentValue_ = nullptr;
-
+
if (Stopped_)
return false;
-
+
TOptsParser copy = *this;
-
+
r = copy.DoNext();
-
+
Swap(copy);
-
+
if (!r) {
Stopped_ = true;
// we are done; check for missing options
Finish();
}
- }
-
+ }
+
if (!r && !OptsDefault_.empty()) {
CurrentOpt_ = OptsDefault_.front();
CurrentValue_ = CurrentOpt_->GetDefaultValue();
OptsDefault_.pop_front();
r = true;
}
-
+
if (r) {
if (CurOpt())
CurOpt()->FireHandlers(this);
}
return r;
- }
-
+ }
+
void TOptsParser::Finish() {
const TOpts::TOptsVector& optvec = Opts_->Opts_;
if (optvec.size() == OptsSeen_.size())
return;
-
+
TVector<TString> missingLong;
TVector<char> missingShort;
-
+
TOpts::TOptsVector::const_iterator it;
for (it = optvec.begin(); it != optvec.end(); ++it) {
const TOpt* opt = (*it).Get();
@@ -343,7 +343,7 @@ namespace NLastGetopt {
continue;
if (OptsSeen_.contains(opt))
continue;
-
+
if (opt->IsRequired()) {
const TOpt::TLongNames& optnames = opt->GetLongNames();
if (!optnames.empty())
@@ -355,18 +355,18 @@ namespace NLastGetopt {
}
continue;
}
-
+
if (opt->HasDefaultValue())
OptsDefault_.push_back(opt);
- }
-
+ }
+
// also indicates subsequent options, if any, haven't been seen actually
OptsSeen_.clear();
-
+
const size_t nmissing = missingLong.size() + missingShort.size();
if (0 == nmissing)
return;
-
+
TUsageException usage;
usage << "The following option";
usage << ((1 == nmissing) ? " is" : "s are");
@@ -377,11 +377,11 @@ namespace NLastGetopt {
usage << " -" << missingShort[i];
throw usage; // don't need lineinfo, just the message
}
-
+
void TOptsParser::PrintUsage(IOutputStream& os, const NColorizer::TColors& colors) const {
Opts_->PrintUsage(ProgramName(), os, colors);
}
-
+
void TOptsParser::PrintUsage(IOutputStream& os) const {
PrintUsage(os, NColorizer::AutoColors(os));
}