aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/getopt/small/opt.cpp
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/getopt/small/opt.cpp
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/getopt/small/opt.cpp')
-rw-r--r--library/cpp/getopt/small/opt.cpp119
1 files changed, 119 insertions, 0 deletions
diff --git a/library/cpp/getopt/small/opt.cpp b/library/cpp/getopt/small/opt.cpp
new file mode 100644
index 0000000000..744501765c
--- /dev/null
+++ b/library/cpp/getopt/small/opt.cpp
@@ -0,0 +1,119 @@
+#include "opt.h"
+
+#include <util/system/progname.h>
+
+#include <ctype.h>
+
+using namespace NLastGetopt;
+
+namespace {
+ struct TOptsNoDefault: public TOpts {
+ TOptsNoDefault(const TStringBuf& optstring = TStringBuf())
+ : TOpts(optstring)
+ {
+ }
+ };
+
+}
+
+void Opt::Init(int argc, char* argv[], const char* optString, const Ion* longOptions, bool longOnly, bool isOpen) {
+ Ions_ = longOptions;
+ Err = true;
+ GotError_ = false;
+ Ind = argc;
+
+ Opts_.Reset(new TOptsNoDefault(optString));
+ for (const Ion* o = longOptions; o != nullptr && o->name != nullptr; ++o) {
+ TOpt* opt;
+ if ((unsigned)o->val < 0x80 && isalnum(o->val)) {
+ opt = &Opts_->CharOption(char(o->val));
+ opt->AddLongName(o->name);
+ } else {
+ Opts_->AddLongOption(o->name);
+ opt = const_cast<TOpt*>(&Opts_->GetLongOption(o->name));
+ }
+ opt->HasArg_ = EHasArg(o->has_arg);
+ opt->UserValue(o);
+ }
+ Opts_->AllowSingleDashForLong_ = longOnly;
+ Opts_->AllowPlusForLong_ = true;
+ Opts_->AllowUnknownCharOptions_ = isOpen;
+ Opts_->AllowUnknownLongOptions_ = false;
+
+ OptsParser_.Reset(new TOptsParser(Opts_.Get(), argc, argv));
+}
+
+Opt::Opt(int argc, char* argv[], const char* optString, const Ion* longOptions, bool longOnly, bool isOpen) {
+ Init(argc, argv, optString, longOptions, longOnly, isOpen);
+}
+
+Opt::Opt(int argc, const char* argv[], const char* optString, const Ion* longOptions, bool longOnly, bool isOpen) {
+ Init(argc, (char**)argv, optString, longOptions, longOnly, isOpen);
+}
+
+int Opt::Get() {
+ return Get(nullptr);
+}
+
+int Opt::Get(int* longOptionIndex) {
+ if (GotError_)
+ return EOF;
+
+ Arg = nullptr;
+
+ try {
+ bool r = OptsParser_->Next();
+ Ind = (int)OptsParser_->Pos_;
+ if (!r) {
+ return EOF;
+ } else {
+ Arg = (char*)OptsParser_->CurVal();
+ if (!OptsParser_->CurOpt()) {
+ // possible if RETURN_IN_ORDER
+ return 1;
+ } else {
+ const Ion* ion = (const Ion*)OptsParser_->CurOpt()->UserValue();
+ if (longOptionIndex) {
+ *longOptionIndex = int(ion - Ions_);
+ }
+ char c = OptsParser_->CurOpt()->GetCharOr0();
+ return c != 0 ? c : ion->val;
+ }
+ }
+ } catch (const NLastGetopt::TException&) {
+ GotError_ = true;
+ if (Err)
+ Cerr << CurrentExceptionMessage() << Endl;
+ return '?';
+ }
+}
+
+void Opt::DummyHelp(IOutputStream& os) {
+ Opts_->PrintUsage(GetProgramName(), os);
+}
+
+int Opt::GetArgC() const {
+ return (int)OptsParser_->Argc_;
+}
+
+const char** Opt::GetArgV() const {
+ return OptsParser_->Argv_;
+}
+
+int opt_get_number(int& argc, char* argv[]) {
+ int num = -1;
+ for (int a = 1; a < argc; a++) {
+ if (*argv[a] == '-' && isdigit((ui8)argv[a][1])) {
+ char* ne;
+ num = strtol(argv[a] + 1, &ne, 10);
+ if (*ne) {
+ memmove(argv[a] + 1, ne, strlen(ne) + 1);
+ } else {
+ for (argc--; a < argc; a++)
+ argv[a] = argv[a + 1];
+ }
+ break;
+ }
+ }
+ return num;
+}