diff options
author | Anton Samokhvalov <pg83@yandex.ru> | 2022-02-10 16:45:15 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:15 +0300 |
commit | 72cb13b4aff9bc9cf22e49251bc8fd143f82538f (patch) | |
tree | da2c34829458c7d4e74bdfbdf85dff449e9e7fb8 /library/cpp/getopt | |
parent | 778e51ba091dc39e7b7fcab2b9cf4dbedfb6f2b5 (diff) | |
download | ydb-72cb13b4aff9bc9cf22e49251bc8fd143f82538f.tar.gz |
Restoring authorship annotation for Anton Samokhvalov <pg83@yandex.ru>. Commit 1 of 2.
Diffstat (limited to 'library/cpp/getopt')
38 files changed, 2271 insertions, 2271 deletions
diff --git a/library/cpp/getopt/last_getopt.h b/library/cpp/getopt/last_getopt.h index d14f05cc5b..55cb627970 100644 --- a/library/cpp/getopt/last_getopt.h +++ b/library/cpp/getopt/last_getopt.h @@ -1,3 +1,3 @@ #pragma once - + #include <library/cpp/getopt/small/last_getopt.h> diff --git a/library/cpp/getopt/last_getopt_demo/demo.cpp b/library/cpp/getopt/last_getopt_demo/demo.cpp index 79426a9cc9..e6a927c0a3 100644 --- a/library/cpp/getopt/last_getopt_demo/demo.cpp +++ b/library/cpp/getopt/last_getopt_demo/demo.cpp @@ -47,7 +47,7 @@ protected: void RegisterOptions(NLastGetopt::TOpts& opts) override { // Brief description for the whole program, will appear in the beginning of a help message. opts.SetTitle("last_getopt_demo -- like wget, but doesn't actually do anything"); - + // Built-in options. opts.AddHelpOption('h'); opts.AddCompletionOption("last_getopt_demo"); diff --git a/library/cpp/getopt/last_getopt_support.h b/library/cpp/getopt/last_getopt_support.h index b71c7045b1..29a656d02a 100644 --- a/library/cpp/getopt/last_getopt_support.h +++ b/library/cpp/getopt/last_getopt_support.h @@ -1,3 +1,3 @@ #pragma once - + #include <library/cpp/getopt/small/last_getopt_support.h> diff --git a/library/cpp/getopt/modchooser.h b/library/cpp/getopt/modchooser.h index 9bf73daf13..26b9a38614 100644 --- a/library/cpp/getopt/modchooser.h +++ b/library/cpp/getopt/modchooser.h @@ -1,3 +1,3 @@ #pragma once - + #include <library/cpp/getopt/small/modchooser.h> diff --git a/library/cpp/getopt/opt.h b/library/cpp/getopt/opt.h index d2a85075bd..2afd477e9c 100644 --- a/library/cpp/getopt/opt.h +++ b/library/cpp/getopt/opt.h @@ -1,3 +1,3 @@ #pragma once - + #include <library/cpp/getopt/small/opt.h> diff --git a/library/cpp/getopt/opt2.h b/library/cpp/getopt/opt2.h index 2d35bc7b29..fbe0d31b7c 100644 --- a/library/cpp/getopt/opt2.h +++ b/library/cpp/getopt/opt2.h @@ -1,3 +1,3 @@ #pragma once - + #include <library/cpp/getopt/small/opt2.h> diff --git a/library/cpp/getopt/posix_getopt.h b/library/cpp/getopt/posix_getopt.h index 8cb7ece624..75d5f235b9 100644 --- a/library/cpp/getopt/posix_getopt.h +++ b/library/cpp/getopt/posix_getopt.h @@ -1,3 +1,3 @@ #pragma once - + #include <library/cpp/getopt/small/posix_getopt.h> diff --git a/library/cpp/getopt/print.cpp b/library/cpp/getopt/print.cpp index 8cf1c62e4d..b49f7aa99f 100644 --- a/library/cpp/getopt/print.cpp +++ b/library/cpp/getopt/print.cpp @@ -1,25 +1,25 @@ #include "last_getopt.h" -#include "last_getopt_support.h" -#include "modchooser.h" -#include "opt.h" -#include "opt2.h" -#include "posix_getopt.h" -#include "ygetopt.h" +#include "last_getopt_support.h" +#include "modchooser.h" +#include "opt.h" +#include "opt2.h" +#include "posix_getopt.h" +#include "ygetopt.h" #include <library/cpp/svnversion/svnversion.h> #include <library/cpp/build_info/build_info.h> namespace NLastGetoptPrivate { TString InitVersionString() { - TString ts = GetProgramSvnVersion(); - ts += "\n"; - ts += GetBuildInfo(); - TString sandboxTaskId = GetSandboxTaskId(); - if (sandboxTaskId != TString("0")) { - ts += "\nSandbox task id: "; - ts += sandboxTaskId; - } - return ts; + TString ts = GetProgramSvnVersion(); + ts += "\n"; + ts += GetBuildInfo(); + TString sandboxTaskId = GetSandboxTaskId(); + if (sandboxTaskId != TString("0")) { + ts += "\nSandbox task id: "; + ts += sandboxTaskId; + } + return ts; } TString InitShortVersionString() { diff --git a/library/cpp/getopt/small/last_getopt.cpp b/library/cpp/getopt/small/last_getopt.cpp index 30669b2c5a..42b1affef1 100644 --- a/library/cpp/getopt/small/last_getopt.cpp +++ b/library/cpp/getopt/small/last_getopt.cpp @@ -1,9 +1,9 @@ -#include "last_getopt.h" - +#include "last_getopt.h" + namespace NLastGetopt { - void PrintUsageAndExit(const TOptsParser* parser) { - parser->PrintUsage(); - exit(0); - } + void PrintUsageAndExit(const TOptsParser* parser) { + parser->PrintUsage(); + exit(0); + } } diff --git a/library/cpp/getopt/small/last_getopt.h b/library/cpp/getopt/small/last_getopt.h index 07687bc914..c472d6ea2c 100644 --- a/library/cpp/getopt/small/last_getopt.h +++ b/library/cpp/getopt/small/last_getopt.h @@ -18,7 +18,7 @@ namespace NLastGetopt { /// Handler to split option value by delimiter into a target container and allow ranges. template <class Container> - struct TOptRangeSplitHandler: public IOptHandler { + struct TOptRangeSplitHandler: public IOptHandler { public: using TContainer = Container; using TValue = typename TContainer::value_type; @@ -57,7 +57,7 @@ namespace NLastGetopt { }; template <class Container> - struct TOptSplitHandler: public IOptHandler { + struct TOptSplitHandler: public IOptHandler { public: using TContainer = Container; using TValue = typename TContainer::value_type; @@ -83,7 +83,7 @@ namespace NLastGetopt { }; template <class TpFunc> - struct TOptKVHandler: public IOptHandler { + struct TOptKVHandler: public IOptHandler { public: using TKey = typename TFunctionArgs<TpFunc>::template TGet<0>; using TValue = typename TFunctionArgs<TpFunc>::template TGet<1>; @@ -101,7 +101,7 @@ namespace NLastGetopt { TStringBuf key, value; if (!curval.TrySplit(KVDelim, key, value)) { throw TUsageException() << "failed to parse opt " << NPrivate::OptToString(curOpt) - << " value " << TString(curval).Quote() << ": expected key" << KVDelim << "value format"; + << " value " << TString(curval).Quote() << ": expected key" << KVDelim << "value format"; } Func(NPrivate::OptFromString<TKey>(key, curOpt), NPrivate::OptFromString<TValue>(value, curOpt)); } @@ -112,21 +112,21 @@ namespace NLastGetopt { char KVDelim; }; - namespace NPrivate { - template <typename TpFunc, typename TpArg> - void THandlerFunctor1<TpFunc, TpArg>::HandleOpt(const TOptsParser* parser) { - const TStringBuf curval = parser->CurValOrDef(!HasDef_); - const TpArg& arg = curval.IsInited() ? OptFromString<TpArg>(curval, parser->CurOpt()) : Def_; - try { - Func_(arg); + namespace NPrivate { + template <typename TpFunc, typename TpArg> + void THandlerFunctor1<TpFunc, TpArg>::HandleOpt(const TOptsParser* parser) { + const TStringBuf curval = parser->CurValOrDef(!HasDef_); + const TpArg& arg = curval.IsInited() ? OptFromString<TpArg>(curval, parser->CurOpt()) : Def_; + try { + Func_(arg); } catch (const TUsageException&) { throw; - } catch (...) { + } catch (...) { throw TUsageException() << "failed to handle opt " << OptToString(parser->CurOpt()) - << " value " << TString(curval).Quote() << ": " << CurrentExceptionMessage(); - } - } + << " value " << TString(curval).Quote() << ": " << CurrentExceptionMessage(); + } + } } - + } diff --git a/library/cpp/getopt/small/last_getopt_easy_setup.cpp b/library/cpp/getopt/small/last_getopt_easy_setup.cpp index c87dedf95e..f2a93056e4 100644 --- a/library/cpp/getopt/small/last_getopt_easy_setup.cpp +++ b/library/cpp/getopt/small/last_getopt_easy_setup.cpp @@ -1,47 +1,47 @@ #include "last_getopt_easy_setup.h" namespace NLastGetopt { - TEasySetup::TEasySetup(const TStringBuf& optstring) - : TOpts(optstring) - { - AddHelpOption(); - } + TEasySetup::TEasySetup(const TStringBuf& optstring) + : TOpts(optstring) + { + AddHelpOption(); + } - TOpt& TEasySetup::AdjustParam(const char* longName, const char* help, const char* argName, bool required) { - Y_ASSERT(longName); - TOpt& o = AddLongOption(longName); - if (help) { - o.Help(help); - } - if (argName) { - o.RequiredArgument(argName); - } else { - o.HasArg(NO_ARGUMENT); - } - if (required) { - o.Required(); - } - return o; - } + TOpt& TEasySetup::AdjustParam(const char* longName, const char* help, const char* argName, bool required) { + Y_ASSERT(longName); + TOpt& o = AddLongOption(longName); + if (help) { + o.Help(help); + } + if (argName) { + o.RequiredArgument(argName); + } else { + o.HasArg(NO_ARGUMENT); + } + if (required) { + o.Required(); + } + return o; + } - TEasySetup& TEasySetup::operator()(char shortName, const char* longName, const char* help, bool required) { - AdjustParam(longName, help, nullptr, required).AddShortName(shortName); - return *this; + TEasySetup& TEasySetup::operator()(char shortName, const char* longName, const char* help, bool required) { + AdjustParam(longName, help, nullptr, required).AddShortName(shortName); + return *this; } - - TEasySetup& TEasySetup::operator()(char shortName, const char* longName, const char* argName, const char* help, bool required) { - AdjustParam(longName, help, argName, required).AddShortName(shortName); - return *this; + + TEasySetup& TEasySetup::operator()(char shortName, const char* longName, const char* argName, const char* help, bool required) { + AdjustParam(longName, help, argName, required).AddShortName(shortName); + return *this; } - - TEasySetup& TEasySetup::operator()(const char* longName, const char* help, bool required) { - AdjustParam(longName, help, nullptr, required); - return *this; + + TEasySetup& TEasySetup::operator()(const char* longName, const char* help, bool required) { + AdjustParam(longName, help, nullptr, required); + return *this; } - TEasySetup& TEasySetup::operator()(const char* longName, const char* argName, const char* help, bool required) { - AdjustParam(longName, help, argName, required); - return *this; - } + TEasySetup& TEasySetup::operator()(const char* longName, const char* argName, const char* help, bool required) { + AdjustParam(longName, help, argName, required); + return *this; + } } diff --git a/library/cpp/getopt/small/last_getopt_easy_setup.h b/library/cpp/getopt/small/last_getopt_easy_setup.h index 60dddda225..f5fabad227 100644 --- a/library/cpp/getopt/small/last_getopt_easy_setup.h +++ b/library/cpp/getopt/small/last_getopt_easy_setup.h @@ -3,7 +3,7 @@ #include "last_getopt_opts.h" namespace NLastGetopt { - /** + /** * Wrapper for TOpts class to make the life a bit easier. * Usual usage: * TEasySetup opts; @@ -16,36 +16,36 @@ namespace NLastGetopt { * * NLastGetopt::TOptsParseResult r(&opts, argc, argv); */ - class TEasySetup: public TOpts { - public: - TEasySetup(const TStringBuf& optstring = TStringBuf()); - TEasySetup& operator()(char shortName, const char* longName, const char* help, bool required = false); - TEasySetup& operator()(char shortName, const char* longName, const char* argName, const char* help, bool required = false); - - template <class TpFunc> - TEasySetup& operator()(char shortName, const char* longName, TpFunc handler, const char* help, bool required = false) { - AdjustParam(longName, help, nullptr, handler, required).AddShortName(shortName); - return *this; - } - - TEasySetup& operator()(const char* longName, const char* help, bool required = false); - TEasySetup& operator()(const char* longName, const char* argName, const char* help, bool required = false); - - template <class TpFunc> - TEasySetup& operator()(const char* longName, TpFunc handler, const char* help, bool required = false) { - AdjustParam(longName, help, nullptr, handler, required); - return *this; - } - - private: - TOpt& AdjustParam(const char* longName, const char* help, const char* argName, bool required); - - template <class TpFunc> - TOpt& AdjustParam(const char* longName, const char* help, const char* argName, TpFunc handler, bool required) { - TOpt& o = AdjustParam(longName, help, argName, required); - o.Handler0(handler); - return o; - } - }; + class TEasySetup: public TOpts { + public: + TEasySetup(const TStringBuf& optstring = TStringBuf()); + TEasySetup& operator()(char shortName, const char* longName, const char* help, bool required = false); + TEasySetup& operator()(char shortName, const char* longName, const char* argName, const char* help, bool required = false); + + template <class TpFunc> + TEasySetup& operator()(char shortName, const char* longName, TpFunc handler, const char* help, bool required = false) { + AdjustParam(longName, help, nullptr, handler, required).AddShortName(shortName); + return *this; + } + + TEasySetup& operator()(const char* longName, const char* help, bool required = false); + TEasySetup& operator()(const char* longName, const char* argName, const char* help, bool required = false); + + template <class TpFunc> + TEasySetup& operator()(const char* longName, TpFunc handler, const char* help, bool required = false) { + AdjustParam(longName, help, nullptr, handler, required); + return *this; + } + + private: + TOpt& AdjustParam(const char* longName, const char* help, const char* argName, bool required); + + template <class TpFunc> + TOpt& AdjustParam(const char* longName, const char* help, const char* argName, TpFunc handler, bool required) { + TOpt& o = AdjustParam(longName, help, argName, required); + o.Handler0(handler); + return o; + } + }; } diff --git a/library/cpp/getopt/small/last_getopt_opt.cpp b/library/cpp/getopt/small/last_getopt_opt.cpp index 9a99437f4b..576b8f03d5 100644 --- a/library/cpp/getopt/small/last_getopt_opt.cpp +++ b/library/cpp/getopt/small/last_getopt_opt.cpp @@ -11,95 +11,95 @@ namespace NLastGetopt { static const TStringBuf ExcludedShortNameChars = "= -\t\n"; static const TStringBuf ExcludedLongNameChars = "= \t\n"; - bool TOpt::NameIs(const TString& name) const { - for (const auto& next : LongNames_) { - if (next == name) - return true; - } - return false; - } - - bool TOpt::CharIs(char c) const { - for (auto next : Chars_) { - if (next == c) - return true; - } - return false; - } - - char TOpt::GetChar() const { - ; - if (Chars_.empty()) - ythrow TConfException() << "no char for option " << this->ToShortString(); - return Chars_.at(0); + bool TOpt::NameIs(const TString& name) const { + for (const auto& next : LongNames_) { + if (next == name) + return true; + } + return false; + } + + bool TOpt::CharIs(char c) const { + for (auto next : Chars_) { + if (next == c) + return true; + } + return false; + } + + char TOpt::GetChar() const { + ; + if (Chars_.empty()) + ythrow TConfException() << "no char for option " << this->ToShortString(); + return Chars_.at(0); } - char TOpt::GetCharOr0() const { - if (Chars_.empty()) - return 0; - return GetChar(); + char TOpt::GetCharOr0() const { + if (Chars_.empty()) + return 0; + return GetChar(); } - TString TOpt::GetName() const { - ; - if (LongNames_.empty()) - ythrow TConfException() << "no name for option " << this->ToShortString(); - return LongNames_.at(0); - } + TString TOpt::GetName() const { + ; + if (LongNames_.empty()) + ythrow TConfException() << "no name for option " << this->ToShortString(); + return LongNames_.at(0); + } - bool TOpt::IsAllowedShortName(unsigned char c) { - return isprint(c) && TStringBuf::npos == ExcludedShortNameChars.find(c); - } + bool TOpt::IsAllowedShortName(unsigned char c) { + return isprint(c) && TStringBuf::npos == ExcludedShortNameChars.find(c); + } - TOpt& TOpt::AddShortName(unsigned char c) { - ; - if (!IsAllowedShortName(c)) + TOpt& TOpt::AddShortName(unsigned char c) { + ; + if (!IsAllowedShortName(c)) throw TUsageException() << "option char '" << c << "' is not allowed"; - Chars_.push_back(c); - return *this; - } - - bool TOpt::IsAllowedLongName(const TString& name, unsigned char* out) { - for (size_t i = 0; i != name.size(); ++i) { - const unsigned char c = name[i]; - if (!isprint(c) || TStringBuf::npos != ExcludedLongNameChars.find(c)) { - if (nullptr != out) - *out = c; - return false; - } + Chars_.push_back(c); + return *this; + } + + bool TOpt::IsAllowedLongName(const TString& name, unsigned char* out) { + for (size_t i = 0; i != name.size(); ++i) { + const unsigned char c = name[i]; + if (!isprint(c) || TStringBuf::npos != ExcludedLongNameChars.find(c)) { + if (nullptr != out) + *out = c; + return false; + } } - return true; + return true; } - TOpt& TOpt::AddLongName(const TString& name) { - ; - unsigned char c = 0; - if (!IsAllowedLongName(name, &c)) + TOpt& TOpt::AddLongName(const TString& name) { + ; + unsigned char c = 0; + if (!IsAllowedLongName(name, &c)) throw TUsageException() << "option char '" << c - << "' in long '" << name << "' is not allowed"; - LongNames_.push_back(name); - return *this; - } - - namespace NPrivate { - TString OptToString(char c); - - TString OptToString(const TString& longOption); - } - - TString TOpt::ToShortString() const { - ; - if (!LongNames_.empty()) - return NPrivate::OptToString(LongNames_.front()); - if (!Chars_.empty()) - return NPrivate::OptToString(Chars_.front()); - return "?"; - } - - void TOpt::FireHandlers(const TOptsParser* parser) const { - for (const auto& handler : Handlers_) { - handler->HandleOpt(parser); - } + << "' in long '" << name << "' is not allowed"; + LongNames_.push_back(name); + return *this; + } + + namespace NPrivate { + TString OptToString(char c); + + TString OptToString(const TString& longOption); + } + + TString TOpt::ToShortString() const { + ; + if (!LongNames_.empty()) + return NPrivate::OptToString(LongNames_.front()); + if (!Chars_.empty()) + return NPrivate::OptToString(Chars_.front()); + return "?"; + } + + void TOpt::FireHandlers(const TOptsParser* parser) const { + for (const auto& handler : Handlers_) { + handler->HandleOpt(parser); + } } TOpt& TOpt::IfPresentDisableCompletionFor(const TOpt& opt) { diff --git a/library/cpp/getopt/small/last_getopt_opt.h b/library/cpp/getopt/small/last_getopt_opt.h index a8dd5adca9..fbd393a310 100644 --- a/library/cpp/getopt/small/last_getopt_opt.h +++ b/library/cpp/getopt/small/last_getopt_opt.h @@ -13,14 +13,14 @@ #include <stdarg.h> namespace NLastGetopt { - enum EHasArg { - NO_ARGUMENT, - REQUIRED_ARGUMENT, - OPTIONAL_ARGUMENT, - DEFAULT_HAS_ARG = REQUIRED_ARGUMENT - }; - - /** + enum EHasArg { + NO_ARGUMENT, + REQUIRED_ARGUMENT, + OPTIONAL_ARGUMENT, + DEFAULT_HAS_ARG = REQUIRED_ARGUMENT + }; + + /** * NLastGetopt::TOpt is a storage of data about exactly one program option. * The data is: parse politics and help information. * @@ -40,28 +40,28 @@ namespace NLastGetopt { * in case of "not given <optional value>, omited optional argument" the <default value> is used * user value: allows to store arbitary pointer for handlers */ - class TOpt { - public: - typedef TVector<char> TShortNames; - typedef TVector<TString> TLongNames; + class TOpt { + public: + typedef TVector<char> TShortNames; + typedef TVector<TString> TLongNames; - protected: - TShortNames Chars_; - TLongNames LongNames_; + protected: + TShortNames Chars_; + TLongNames LongNames_; - private: - typedef TMaybe<TString> TdOptVal; - typedef TVector<TSimpleSharedPtr<IOptHandler>> TOptHandlers; + private: + typedef TMaybe<TString> TdOptVal; + typedef TVector<TSimpleSharedPtr<IOptHandler>> TOptHandlers; - public: + public: bool Hidden_ = false; // is visible in help TString ArgTitle_; // the name of argument in help output TString Help_; // the help string TString CompletionHelp_; // the help string that's used in completion script, a shorter version of Help_ TString CompletionArgHelp_; // the description of argument in completion script - EHasArg HasArg_ = DEFAULT_HAS_ARG; // the argument parsing politics - bool Required_ = false; // option existence politics + EHasArg HasArg_ = DEFAULT_HAS_ARG; // the argument parsing politics + bool Required_ = false; // option existence politics bool AllowMultipleCompletion_ = false; // let the completer know that this option can occur more than once @@ -72,104 +72,104 @@ namespace NLastGetopt { TVector<size_t> DisableCompletionForFreeArg_; NComp::ICompleterPtr Completer_; - private: - //Handlers information - const void* UserValue_ = nullptr; - TdOptVal OptionalValue_; - TdOptVal DefaultValue_; - TOptHandlers Handlers_; + private: + //Handlers information + const void* UserValue_ = nullptr; + TdOptVal OptionalValue_; + TdOptVal DefaultValue_; + TOptHandlers Handlers_; - public: - /** + public: + /** * Checks if given char can be a short name * @param c char to check */ - static bool IsAllowedShortName(unsigned char c); + static bool IsAllowedShortName(unsigned char c); - /** + /** * Checks if given string can be a long name * @param name string to check * @param c if given, the first bad charecter will be saved in c */ - static bool IsAllowedLongName(const TString& name, unsigned char* c = nullptr); + static bool IsAllowedLongName(const TString& name, unsigned char* c = nullptr); - /** + /** * @return one of the expected representations of the option. * If the option has short names, will return "-<char>" * Otherwise will return "--<long name>" */ - TString ToShortString() const; + TString ToShortString() const; - /** + /** * check if given string is one of the long names * * @param name string to check */ - bool NameIs(const TString& name) const; + bool NameIs(const TString& name) const; - /** + /** * check if given char is one of the short names * * @param c char to check */ - bool CharIs(char c) const; + bool CharIs(char c) const; - /** + /** * If string has long names - will return one of them * Otherwise will throw */ - TString GetName() const; + TString GetName() const; - /** + /** * adds short alias for the option * * @param c new short name * * @return self */ - TOpt& AddShortName(unsigned char c); + TOpt& AddShortName(unsigned char c); - /** + /** * return all short names of the option */ - const TShortNames& GetShortNames() const { - return Chars_; - } + const TShortNames& GetShortNames() const { + return Chars_; + } - /** + /** * adds long alias for the option * * @param name new long name * * @return self */ - TOpt& AddLongName(const TString& name); + TOpt& AddLongName(const TString& name); - /** + /** * return all long names of the option */ - const TLongNames& GetLongNames() const { - return LongNames_; - } + const TLongNames& GetLongNames() const { + return LongNames_; + } - /** + /** * @return one of short names of the opt. If there is no short names exception is raised. */ - char GetChar() const; + char GetChar() const; - /** + /** * @return one of short names of the opt. If there is no short names '\0' returned. */ - char GetCharOr0() const; + char GetCharOr0() const; - /** + /** * @returns argument parsing politics */ - const EHasArg& GetHasArg() const { - return HasArg_; - } + const EHasArg& GetHasArg() const { + return HasArg_; + } - /** + /** * sets argument parsing politics * * Note: its better use one of RequiredArgument/NoArgument/OptionalArgument methods @@ -177,51 +177,51 @@ namespace NLastGetopt { * @param hasArg new argument parsing mode * @return self */ - TOpt& HasArg(EHasArg hasArg) { - HasArg_ = hasArg; - return *this; - } + TOpt& HasArg(EHasArg hasArg) { + HasArg_ = hasArg; + return *this; + } - /** + /** * @returns argument title */ - TString GetArgTitle() const { - return ArgTitle_; - } + TString GetArgTitle() const { + return ArgTitle_; + } - /** + /** * sets argument parsing politics into REQUIRED_ARGUMENT * * @param title the new name of argument in help output * @return self */ - TOpt& RequiredArgument(const TString& title = "") { - ArgTitle_ = title; - return HasArg(REQUIRED_ARGUMENT); - } + TOpt& RequiredArgument(const TString& title = "") { + ArgTitle_ = title; + return HasArg(REQUIRED_ARGUMENT); + } - /** + /** * sets argument parsing politics into NO_ARGUMENT * * @return self */ - TOpt& NoArgument() { - return HasArg(NO_ARGUMENT); - } + TOpt& NoArgument() { + return HasArg(NO_ARGUMENT); + } - /** + /** * sets argument parsing politics into OPTIONAL_ARGUMENT * for details see NLastGetopt::TOpt * * @param title the new name of argument in help output * @return self */ - TOpt& OptionalArgument(const TString& title = "") { - ArgTitle_ = title; - return HasArg(OPTIONAL_ARGUMENT); - } + TOpt& OptionalArgument(const TString& title = "") { + ArgTitle_ = title; + return HasArg(OPTIONAL_ARGUMENT); + } - /** + /** * sets argument parsing politics into OPTIONAL_ARGUMENT * sets the <optional value> into given * @@ -231,110 +231,110 @@ namespace NLastGetopt { * @param title the new name of argument in help output * @return self */ - TOpt& OptionalValue(const TString& val, const TString& title = "") { - OptionalValue_ = val; - return OptionalArgument(title); - } + TOpt& OptionalValue(const TString& val, const TString& title = "") { + OptionalValue_ = val; + return OptionalArgument(title); + } - /** + /** * checks if "argument parsing politics" is OPTIONAL_ARGUMENT and the <optional value> is set. */ - bool HasOptionalValue() const { - return OPTIONAL_ARGUMENT == HasArg_ && OptionalValue_; - } + bool HasOptionalValue() const { + return OPTIONAL_ARGUMENT == HasArg_ && OptionalValue_; + } - /** + /** * @return optional value * throws exception if optional value wasn't set */ const TString& GetOptionalValue() const { - return *OptionalValue_; - } + return *OptionalValue_; + } - /** + /** * sets <default value> * @return self */ - template <typename T> - TOpt& DefaultValue(const T& val) { - DefaultValue_ = ToString(val); - return *this; - } + template <typename T> + TOpt& DefaultValue(const T& val) { + DefaultValue_ = ToString(val); + return *this; + } - /** + /** * checks if default value is set. */ - bool HasDefaultValue() const { - return DefaultValue_.Defined(); - } + bool HasDefaultValue() const { + return DefaultValue_.Defined(); + } - /** + /** * @return default value * throws exception if <default value> wasn't set */ const TString& GetDefaultValue() const { - return *DefaultValue_; - } + return *DefaultValue_; + } - /** + /** * sets the option to be required * @return self */ - TOpt& Required() { - Required_ = true; - return *this; - } + TOpt& Required() { + Required_ = true; + return *this; + } - /** + /** * sets the option to be optional * @return self */ - TOpt& Optional() { - Required_ = false; - return *this; - } + TOpt& Optional() { + Required_ = false; + return *this; + } - /** + /** * @return true if the option is required */ - bool IsRequired() const { - return Required_; - } + bool IsRequired() const { + return Required_; + } - /** + /** * sets the option to be hidden (invisible in help) * @return self */ - TOpt& Hidden() { - Hidden_ = true; - return *this; - } + TOpt& Hidden() { + Hidden_ = true; + return *this; + } - /** + /** * @return true if the option is hidden */ - bool IsHidden() const { - return Hidden_; - } + bool IsHidden() const { + return Hidden_; + } - /** + /** * sets the <user value> * @return self * for details see NLastGetopt::TOpt */ - TOpt& UserValue(const void* userval) { - UserValue_ = userval; - return *this; - } + TOpt& UserValue(const void* userval) { + UserValue_ = userval; + return *this; + } - /** + /** * @return user value */ - const void* UserValue() const { - return UserValue_; - } + const void* UserValue() const { + return UserValue_; + } - /** + /** * Set help string that appears with `--help`. Unless `CompletionHelp` is given, this message will also be used * in completion script. In this case, don't make it too long, don't start it with a capital letter and don't * end it with a full stop. @@ -367,19 +367,19 @@ namespace NLastGetopt { * See more on completion descriptions codestyle: * https://github.com/zsh-users/zsh/blob/master/Etc/completion-style-guide#L43 */ - TOpt& Help(const TString& help) { - Help_ = help; - return *this; - } + TOpt& Help(const TString& help) { + Help_ = help; + return *this; + } - /** + /** * Get help string. */ const TString& GetHelp() const { - return Help_; - } + return Help_; + } - /** + /** * Set help string that appears when argument completer lists available options. * * See `Help` function for info on how this is different from setting `Help` and `CompletionArgHelp`. @@ -545,64 +545,64 @@ namespace NLastGetopt { /** * Run handlers for this option. */ - void FireHandlers(const TOptsParser* parser) const; - - private: - TOpt& HandlerImpl(IOptHandler* handler) { - Handlers_.push_back(handler); - return *this; - } - - public: - template <typename TpFunc> - TOpt& Handler0(TpFunc func) { // functor taking no parameters - return HandlerImpl(new NPrivate::THandlerFunctor0<TpFunc>(func)); - } - - template <typename TpFunc> - TOpt& Handler1(TpFunc func) { // functor taking one parameter - return HandlerImpl(new NPrivate::THandlerFunctor1<TpFunc>(func)); - } - template <typename TpArg, typename TpFunc> - TOpt& Handler1T(TpFunc func) { - return HandlerImpl(new NPrivate::THandlerFunctor1<TpFunc, TpArg>(func)); - } - template <typename TpArg, typename TpFunc> - TOpt& Handler1T(const TpArg& def, TpFunc func) { - return HandlerImpl(new NPrivate::THandlerFunctor1<TpFunc, TpArg>(func, def)); - } - template <typename TpArg, typename TpArg2, typename TpFunc> - TOpt& Handler1T2(const TpArg2& def, TpFunc func) { - return HandlerImpl(new NPrivate::THandlerFunctor1<TpFunc, TpArg>(func, def)); - } - - TOpt& Handler(void (*f)()) { - return Handler0(f); - } - TOpt& Handler(void (*f)(const TOptsParser*)) { - return Handler1(f); - } - - TOpt& Handler(TAutoPtr<IOptHandler> handler) { - return HandlerImpl(handler.Release()); - } - - template <typename T> // T extends IOptHandler - TOpt& Handler(TAutoPtr<T> handler) { - return HandlerImpl(handler.Release()); - } - - // Stores FromString<T>(arg) in *target - // T maybe anything with FromString<T>(const TStringBuf&) defined - template <typename TpVal, typename T> - TOpt& StoreResultT(T* target) { - return Handler1T<TpVal>(NPrivate::TStoreResultFunctor<T, TpVal>(target)); - } - - template <typename T> - TOpt& StoreResult(T* target) { - return StoreResultT<T>(target); - } + void FireHandlers(const TOptsParser* parser) const; + + private: + TOpt& HandlerImpl(IOptHandler* handler) { + Handlers_.push_back(handler); + return *this; + } + + public: + template <typename TpFunc> + TOpt& Handler0(TpFunc func) { // functor taking no parameters + return HandlerImpl(new NPrivate::THandlerFunctor0<TpFunc>(func)); + } + + template <typename TpFunc> + TOpt& Handler1(TpFunc func) { // functor taking one parameter + return HandlerImpl(new NPrivate::THandlerFunctor1<TpFunc>(func)); + } + template <typename TpArg, typename TpFunc> + TOpt& Handler1T(TpFunc func) { + return HandlerImpl(new NPrivate::THandlerFunctor1<TpFunc, TpArg>(func)); + } + template <typename TpArg, typename TpFunc> + TOpt& Handler1T(const TpArg& def, TpFunc func) { + return HandlerImpl(new NPrivate::THandlerFunctor1<TpFunc, TpArg>(func, def)); + } + template <typename TpArg, typename TpArg2, typename TpFunc> + TOpt& Handler1T2(const TpArg2& def, TpFunc func) { + return HandlerImpl(new NPrivate::THandlerFunctor1<TpFunc, TpArg>(func, def)); + } + + TOpt& Handler(void (*f)()) { + return Handler0(f); + } + TOpt& Handler(void (*f)(const TOptsParser*)) { + return Handler1(f); + } + + TOpt& Handler(TAutoPtr<IOptHandler> handler) { + return HandlerImpl(handler.Release()); + } + + template <typename T> // T extends IOptHandler + TOpt& Handler(TAutoPtr<T> handler) { + return HandlerImpl(handler.Release()); + } + + // Stores FromString<T>(arg) in *target + // T maybe anything with FromString<T>(const TStringBuf&) defined + template <typename TpVal, typename T> + TOpt& StoreResultT(T* target) { + return Handler1T<TpVal>(NPrivate::TStoreResultFunctor<T, TpVal>(target)); + } + + template <typename T> + TOpt& StoreResult(T* target) { + return StoreResultT<T>(target); + } // Uses TMaybe<T> to store FromString<T>(arg) template <typename T> @@ -610,15 +610,15 @@ namespace NLastGetopt { return StoreResultT<T>(target); } - template <typename TpVal, typename T, typename TpDef> - TOpt& StoreResultT(T* target, const TpDef& def) { - return Handler1T<TpVal>(def, NPrivate::TStoreResultFunctor<T, TpVal>(target)); - } + template <typename TpVal, typename T, typename TpDef> + TOpt& StoreResultT(T* target, const TpDef& def) { + return Handler1T<TpVal>(def, NPrivate::TStoreResultFunctor<T, TpVal>(target)); + } - template <typename T, typename TpDef> - TOpt& StoreResult(T* target, const TpDef& def) { - return StoreResultT<T>(target, def); - } + template <typename T, typename TpDef> + TOpt& StoreResult(T* target, const TpDef& def) { + return StoreResultT<T>(target, def); + } template <typename T> TOpt& StoreResultDef(T* target) { @@ -632,51 +632,51 @@ namespace NLastGetopt { return StoreResultT<T>(target, def); } - // Sugar for storing flags (option without arguments) to boolean vars - TOpt& SetFlag(bool* target) { - return DefaultValue("0").StoreResult(target, true); - } + // Sugar for storing flags (option without arguments) to boolean vars + TOpt& SetFlag(bool* target) { + return DefaultValue("0").StoreResult(target, true); + } // Similar to store_true in Python's argparse TOpt& StoreTrue(bool* target) { return NoArgument().SetFlag(target); } - template <typename TpVal, typename T, typename TpFunc> - TOpt& StoreMappedResultT(T* target, const TpFunc& func) { - return Handler1T<TpVal>(NPrivate::TStoreMappedResultFunctor<T, TpFunc, TpVal>(target, func)); - } - - template <typename T, typename TpFunc> - TOpt& StoreMappedResult(T* target, const TpFunc& func) { - return StoreMappedResultT<T>(target, func); - } - - // Stores given value in *target if the option is present. - // TValue must be a copyable type, constructible from TParam. - // T must be a copyable type, assignable from TValue. - template <typename TValue, typename T, typename TParam> - TOpt& StoreValueT(T* target, const TParam& value) { - return Handler1(NPrivate::TStoreValueFunctor<T, TValue>(target, value)); - } - - // save value as target type - template <typename T, typename TParam> - TOpt& StoreValue(T* target, const TParam& value) { - return StoreValueT<T>(target, value); - } - - // save value as its original type (2nd template parameter) - template <typename T, typename TValue> - TOpt& StoreValue2(T* target, const TValue& value) { - return StoreValueT<TValue>(target, value); - } - - // Appends FromString<T>(arg) to *target for each argument - template <typename T> - TOpt& AppendTo(TVector<T>* target) { + template <typename TpVal, typename T, typename TpFunc> + TOpt& StoreMappedResultT(T* target, const TpFunc& func) { + return Handler1T<TpVal>(NPrivate::TStoreMappedResultFunctor<T, TpFunc, TpVal>(target, func)); + } + + template <typename T, typename TpFunc> + TOpt& StoreMappedResult(T* target, const TpFunc& func) { + return StoreMappedResultT<T>(target, func); + } + + // Stores given value in *target if the option is present. + // TValue must be a copyable type, constructible from TParam. + // T must be a copyable type, assignable from TValue. + template <typename TValue, typename T, typename TParam> + TOpt& StoreValueT(T* target, const TParam& value) { + return Handler1(NPrivate::TStoreValueFunctor<T, TValue>(target, value)); + } + + // save value as target type + template <typename T, typename TParam> + TOpt& StoreValue(T* target, const TParam& value) { + return StoreValueT<T>(target, value); + } + + // save value as its original type (2nd template parameter) + template <typename T, typename TValue> + TOpt& StoreValue2(T* target, const TValue& value) { + return StoreValueT<TValue>(target, value); + } + + // Appends FromString<T>(arg) to *target for each argument + template <typename T> + TOpt& AppendTo(TVector<T>* target) { return Handler1T<T>([target](auto&& value) { target->push_back(std::move(value)); }); - } + } // Appends FromString<T>(arg) to *target for each argument template <typename T> @@ -690,23 +690,23 @@ namespace NLastGetopt { return Handler1T<TString>([target](TString arg) { target->emplace_back(std::move(arg)); } ); } - template <class Container> - TOpt& SplitHandler(Container* target, const char delim) { - return Handler(new NLastGetopt::TOptSplitHandler<Container>(target, delim)); - } + template <class Container> + TOpt& SplitHandler(Container* target, const char delim) { + return Handler(new NLastGetopt::TOptSplitHandler<Container>(target, delim)); + } - template <class Container> - TOpt& RangeSplitHandler(Container* target, const char elementsDelim, const char rangesDelim) { - return Handler(new NLastGetopt::TOptRangeSplitHandler<Container>(target, elementsDelim, rangesDelim)); - } + template <class Container> + TOpt& RangeSplitHandler(Container* target, const char elementsDelim, const char rangesDelim) { + return Handler(new NLastGetopt::TOptRangeSplitHandler<Container>(target, elementsDelim, rangesDelim)); + } - template <class TpFunc> - TOpt& KVHandler(TpFunc func, const char kvdelim = '=') { - return Handler(new NLastGetopt::TOptKVHandler<TpFunc>(func, kvdelim)); - } - }; + template <class TpFunc> + TOpt& KVHandler(TpFunc func, const char kvdelim = '=') { + return Handler(new NLastGetopt::TOptKVHandler<TpFunc>(func, kvdelim)); + } + }; - /** + /** * NLastGetopt::TFreeArgSpec is a storage of data about free argument. * The data is help information and (maybe) linked named argument. * @@ -714,14 +714,14 @@ namespace NLastGetopt { * help string * argument name (title) */ - struct TFreeArgSpec { - TFreeArgSpec() = default; + struct TFreeArgSpec { + TFreeArgSpec() = default; TFreeArgSpec(const TString& title, const TString& help = TString(), bool optional = false) : Title_(title) , Help_(help) , Optional_(optional) - { - } + { + } TString Title_; TString Help_; @@ -808,5 +808,5 @@ namespace NLastGetopt { Completer_ = std::move(completer); return *this; } - }; -} + }; +} diff --git a/library/cpp/getopt/small/last_getopt_opts.cpp b/library/cpp/getopt/small/last_getopt_opts.cpp index 03c432849f..bb04f03a7e 100644 --- a/library/cpp/getopt/small/last_getopt_opts.cpp +++ b/library/cpp/getopt/small/last_getopt_opts.cpp @@ -7,7 +7,7 @@ #include <util/stream/format.h> #include <util/charset/utf8.h> - + #include <stdlib.h> namespace NLastGetoptPrivate { @@ -19,212 +19,212 @@ namespace NLastGetoptPrivate { static TString data; return data; } -} +} -namespace NLastGetopt { +namespace NLastGetopt { static const TStringBuf SPad = " "; - void PrintVersionAndExit(const TOptsParser*) { + void PrintVersionAndExit(const TOptsParser*) { Cout << (NLastGetoptPrivate::VersionString() ? NLastGetoptPrivate::VersionString() : "program version: not linked with library/cpp/getopt") << Endl; - exit(NLastGetoptPrivate::VersionString().empty()); - } + exit(NLastGetoptPrivate::VersionString().empty()); + } void PrintShortVersionAndExit(const TString& appName) { Cout << appName << " version " << (NLastGetoptPrivate::ShortVersionString() ? NLastGetoptPrivate::ShortVersionString() : "not linked with library/cpp/getopt") << Endl; exit(NLastGetoptPrivate::ShortVersionString().empty()); } - // Like TString::Quote(), but does not quote digits-only string - static TString QuoteForHelp(const TString& str) { - if (str.empty()) - return str.Quote(); - for (size_t i = 0; i < str.size(); ++i) { - if (!isdigit(str[i])) - return str.Quote(); - } - return str; - } - - namespace NPrivate { - TString OptToString(char c) { - TStringStream ss; - ss << "-" << c; - return ss.Str(); - } - - TString OptToString(const TString& longOption) { - TStringStream ss; - ss << "--" << longOption; - return ss.Str(); - } - - TString OptToString(const TOpt* opt) { - return opt->ToShortString(); - } - } - - TOpts::TOpts(const TStringBuf& optstring) - : ArgPermutation_(DEFAULT_ARG_PERMUTATION) - , AllowSingleDashForLong_(false) - , AllowPlusForLong_(false) - , AllowUnknownCharOptions_(false) - , AllowUnknownLongOptions_(false) - , FreeArgsMin_(0) + // Like TString::Quote(), but does not quote digits-only string + static TString QuoteForHelp(const TString& str) { + if (str.empty()) + return str.Quote(); + for (size_t i = 0; i < str.size(); ++i) { + if (!isdigit(str[i])) + return str.Quote(); + } + return str; + } + + namespace NPrivate { + TString OptToString(char c) { + TStringStream ss; + ss << "-" << c; + return ss.Str(); + } + + TString OptToString(const TString& longOption) { + TStringStream ss; + ss << "--" << longOption; + return ss.Str(); + } + + TString OptToString(const TOpt* opt) { + return opt->ToShortString(); + } + } + + TOpts::TOpts(const TStringBuf& optstring) + : ArgPermutation_(DEFAULT_ARG_PERMUTATION) + , AllowSingleDashForLong_(false) + , AllowPlusForLong_(false) + , AllowUnknownCharOptions_(false) + , AllowUnknownLongOptions_(false) + , FreeArgsMin_(0) , FreeArgsMax_(UNLIMITED_ARGS) - { - if (!optstring.empty()) { - AddCharOptions(optstring); - } - AddVersionOption(0); - } - - void TOpts::AddCharOptions(const TStringBuf& optstring) { - size_t p = 0; - if (optstring[p] == '+') { - ArgPermutation_ = REQUIRE_ORDER; - ++p; - } else if (optstring[p] == '-') { - ArgPermutation_ = RETURN_IN_ORDER; - ++p; - } - - while (p < optstring.size()) { - char c = optstring[p]; - p++; - EHasArg ha = NO_ARGUMENT; - if (p < optstring.size() && optstring[p] == ':') { - ha = REQUIRED_ARGUMENT; - p++; + { + if (!optstring.empty()) { + AddCharOptions(optstring); + } + AddVersionOption(0); + } + + void TOpts::AddCharOptions(const TStringBuf& optstring) { + size_t p = 0; + if (optstring[p] == '+') { + ArgPermutation_ = REQUIRE_ORDER; + ++p; + } else if (optstring[p] == '-') { + ArgPermutation_ = RETURN_IN_ORDER; + ++p; + } + + while (p < optstring.size()) { + char c = optstring[p]; + p++; + EHasArg ha = NO_ARGUMENT; + if (p < optstring.size() && optstring[p] == ':') { + ha = REQUIRED_ARGUMENT; + p++; + } + if (p < optstring.size() && optstring[p] == ':') { + ha = OPTIONAL_ARGUMENT; + p++; + } + AddCharOption(c, ha); + } + } + + const TOpt* TOpts::FindLongOption(const TStringBuf& name) const { + for (const auto& Opt : Opts_) { + const TOpt* opt = Opt.Get(); + if (IsIn(opt->GetLongNames(), name)) + return opt; + } + return nullptr; + } + + TOpt* TOpts::FindLongOption(const TStringBuf& name) { + for (auto& Opt : Opts_) { + TOpt* opt = Opt.Get(); + if (IsIn(opt->GetLongNames(), name)) + return opt; + } + return nullptr; + } + + const TOpt* TOpts::FindCharOption(char c) const { + for (const auto& Opt : Opts_) { + const TOpt* opt = Opt.Get(); + if (IsIn(opt->GetShortNames(), c)) + return opt; + } + return nullptr; + } + + TOpt* TOpts::FindCharOption(char c) { + for (auto& Opt : Opts_) { + TOpt* opt = Opt.Get(); + if (IsIn(opt->GetShortNames(), c)) + return opt; + } + return nullptr; + } + + const TOpt& TOpts::GetCharOption(char c) const { + const TOpt* option = FindCharOption(c); + if (!option) + ythrow TException() << "unknown char option '" << c << "'"; + return *option; + } + + TOpt& TOpts::GetCharOption(char c) { + TOpt* option = FindCharOption(c); + if (!option) + ythrow TException() << "unknown char option '" << c << "'"; + return *option; + } + + const TOpt& TOpts::GetLongOption(const TStringBuf& name) const { + const TOpt* option = FindLongOption(name); + if (!option) + ythrow TException() << "unknown option " << name; + return *option; + } + + TOpt& TOpts::GetLongOption(const TStringBuf& name) { + TOpt* option = FindLongOption(name); + if (!option) + ythrow TException() << "unknown option " << name; + return *option; + } + + bool TOpts::HasAnyShortOption() const { + for (const auto& Opt : Opts_) { + const TOpt* opt = Opt.Get(); + if (!opt->GetShortNames().empty()) + return true; + } + return false; + } + + bool TOpts::HasAnyLongOption() const { + for (const auto& Opt : Opts_) { + TOpt* opt = Opt.Get(); + if (!opt->GetLongNames().empty()) + return true; + } + return false; + } + + void TOpts::Validate() const { + for (TOptsVector::const_iterator i = Opts_.begin(); i != Opts_.end(); ++i) { + TOpt* opt = i->Get(); + const TOpt::TShortNames& shortNames = opt->GetShortNames(); + for (auto c : shortNames) { + for (TOptsVector::const_iterator j = i + 1; j != Opts_.end(); ++j) { + TOpt* nextOpt = j->Get(); + if (nextOpt->CharIs(c)) + ythrow TConfException() << "option " + << NPrivate::OptToString(c) + << " is defined more than once"; + } } - if (p < optstring.size() && optstring[p] == ':') { - ha = OPTIONAL_ARGUMENT; - p++; + const TOpt::TLongNames& longNames = opt->GetLongNames(); + for (const auto& longName : longNames) { + for (TOptsVector::const_iterator j = i + 1; j != Opts_.end(); ++j) { + TOpt* nextOpt = j->Get(); + if (nextOpt->NameIs(longName)) + ythrow TConfException() << "option " + << NPrivate::OptToString(longName) + << " is defined more than once"; + } } - AddCharOption(c, ha); - } - } - - const TOpt* TOpts::FindLongOption(const TStringBuf& name) const { - for (const auto& Opt : Opts_) { - const TOpt* opt = Opt.Get(); - if (IsIn(opt->GetLongNames(), name)) - return opt; - } - return nullptr; - } - - TOpt* TOpts::FindLongOption(const TStringBuf& name) { - for (auto& Opt : Opts_) { - TOpt* opt = Opt.Get(); - if (IsIn(opt->GetLongNames(), name)) - return opt; - } - return nullptr; - } - - const TOpt* TOpts::FindCharOption(char c) const { - for (const auto& Opt : Opts_) { - const TOpt* opt = Opt.Get(); - if (IsIn(opt->GetShortNames(), c)) - return opt; - } - return nullptr; - } - - TOpt* TOpts::FindCharOption(char c) { - for (auto& Opt : Opts_) { - TOpt* opt = Opt.Get(); - if (IsIn(opt->GetShortNames(), c)) - return opt; - } - return nullptr; - } - - const TOpt& TOpts::GetCharOption(char c) const { - const TOpt* option = FindCharOption(c); - if (!option) - ythrow TException() << "unknown char option '" << c << "'"; - return *option; - } - - TOpt& TOpts::GetCharOption(char c) { - TOpt* option = FindCharOption(c); - if (!option) - ythrow TException() << "unknown char option '" << c << "'"; - return *option; - } - - const TOpt& TOpts::GetLongOption(const TStringBuf& name) const { - const TOpt* option = FindLongOption(name); - if (!option) - ythrow TException() << "unknown option " << name; - return *option; - } - - TOpt& TOpts::GetLongOption(const TStringBuf& name) { - TOpt* option = FindLongOption(name); - if (!option) - ythrow TException() << "unknown option " << name; - return *option; - } - - bool TOpts::HasAnyShortOption() const { - for (const auto& Opt : Opts_) { - const TOpt* opt = Opt.Get(); - if (!opt->GetShortNames().empty()) - return true; } - return false; - } - - bool TOpts::HasAnyLongOption() const { - for (const auto& Opt : Opts_) { - TOpt* opt = Opt.Get(); - if (!opt->GetLongNames().empty()) - return true; - } - return false; - } - - void TOpts::Validate() const { - for (TOptsVector::const_iterator i = Opts_.begin(); i != Opts_.end(); ++i) { - TOpt* opt = i->Get(); - const TOpt::TShortNames& shortNames = opt->GetShortNames(); - for (auto c : shortNames) { - for (TOptsVector::const_iterator j = i + 1; j != Opts_.end(); ++j) { - TOpt* nextOpt = j->Get(); - if (nextOpt->CharIs(c)) - ythrow TConfException() << "option " - << NPrivate::OptToString(c) - << " is defined more than once"; - } - } - const TOpt::TLongNames& longNames = opt->GetLongNames(); - for (const auto& longName : longNames) { - for (TOptsVector::const_iterator j = i + 1; j != Opts_.end(); ++j) { - TOpt* nextOpt = j->Get(); - if (nextOpt->NameIs(longName)) - ythrow TConfException() << "option " - << NPrivate::OptToString(longName) - << " is defined more than once"; - } - } - } - if (FreeArgsMax_ < FreeArgsMin_) { - ythrow TConfException() << "FreeArgsMax must be >= FreeArgsMin"; - } - if (!FreeArgSpecs_.empty() && FreeArgSpecs_.rbegin()->first >= FreeArgsMax_) { - ythrow TConfException() << "Described args count is greater than FreeArgsMax. Either increase FreeArgsMax or remove unreachable descriptions"; - } - } - - TOpt& TOpts::AddOption(const TOpt& option) { - if (option.GetShortNames().empty() && option.GetLongNames().empty()) - ythrow TConfException() << "bad option: no chars, no long names"; - Opts_.push_back(new TOpt(option)); - return *Opts_.back(); - } - + if (FreeArgsMax_ < FreeArgsMin_) { + ythrow TConfException() << "FreeArgsMax must be >= FreeArgsMin"; + } + if (!FreeArgSpecs_.empty() && FreeArgSpecs_.rbegin()->first >= FreeArgsMax_) { + ythrow TConfException() << "Described args count is greater than FreeArgsMax. Either increase FreeArgsMax or remove unreachable descriptions"; + } + } + + TOpt& TOpts::AddOption(const TOpt& option) { + if (option.GetShortNames().empty() && option.GetLongNames().empty()) + ythrow TConfException() << "bad option: no chars, no long names"; + Opts_.push_back(new TOpt(option)); + return *Opts_.back(); + } + TOpt& TOpts::AddCompletionOption(TString command, TString longName) { if (TOpt* o = FindLongOption(longName)) { return *o; @@ -252,19 +252,19 @@ namespace NLastGetopt { .IfPresentDisableCompletionFor(opt1); } - size_t TOpts::IndexOf(const TOpt* opt) const { - TOptsVector::const_iterator it = std::find(Opts_.begin(), Opts_.end(), opt); - if (it == Opts_.end()) - ythrow TException() << "unknown option"; - return it - Opts_.begin(); + size_t TOpts::IndexOf(const TOpt* opt) const { + TOptsVector::const_iterator it = std::find(Opts_.begin(), Opts_.end(), opt); + if (it == Opts_.end()) + ythrow TException() << "unknown option"; + return it - Opts_.begin(); } TStringBuf TOpts::GetFreeArgTitle(size_t pos) const { if (FreeArgSpecs_.contains(pos)) { return FreeArgSpecs_.at(pos).GetTitle(DefaultFreeArgTitle_); - } + } return DefaultFreeArgTitle_; - } + } void TOpts::SetFreeArgTitle(size_t pos, const TString& title, const TString& help, bool optional) { FreeArgSpecs_[pos] = TFreeArgSpec(title, help, optional); @@ -274,56 +274,56 @@ namespace NLastGetopt { return FreeArgSpecs_[pos]; } - static TString FormatOption(const TOpt* option, const NColorizer::TColors& colors) { - TStringStream result; - const TOpt::TShortNames& shorts = option->GetShortNames(); - const TOpt::TLongNames& longs = option->GetLongNames(); - - const size_t nopts = shorts.size() + longs.size(); - const bool multiple = 1 < nopts; - if (multiple) - result << '{'; - for (size_t i = 0; i < nopts; ++i) { - if (multiple && 0 != i) - result << '|'; - - if (i < shorts.size()) // short - result << colors.GreenColor() << '-' << shorts[i] << colors.OldColor(); - else - result << colors.GreenColor() << "--" << longs[i - shorts.size()] << colors.OldColor(); - } - if (multiple) - result << '}'; - - static const TString metavarDef("VAL"); - const TString& title = option->GetArgTitle(); + static TString FormatOption(const TOpt* option, const NColorizer::TColors& colors) { + TStringStream result; + const TOpt::TShortNames& shorts = option->GetShortNames(); + const TOpt::TLongNames& longs = option->GetLongNames(); + + const size_t nopts = shorts.size() + longs.size(); + const bool multiple = 1 < nopts; + if (multiple) + result << '{'; + for (size_t i = 0; i < nopts; ++i) { + if (multiple && 0 != i) + result << '|'; + + if (i < shorts.size()) // short + result << colors.GreenColor() << '-' << shorts[i] << colors.OldColor(); + else + result << colors.GreenColor() << "--" << longs[i - shorts.size()] << colors.OldColor(); + } + if (multiple) + result << '}'; + + static const TString metavarDef("VAL"); + const TString& title = option->GetArgTitle(); const TString& metavar = title.empty() ? metavarDef : title; - if (option->GetHasArg() == OPTIONAL_ARGUMENT) { - result << " [" << metavar; - if (option->HasOptionalValue()) - result << ':' << option->GetOptionalValue(); - result << ']'; - } else if (option->GetHasArg() == REQUIRED_ARGUMENT) - result << ' ' << metavar; + if (option->GetHasArg() == OPTIONAL_ARGUMENT) { + result << " [" << metavar; + if (option->HasOptionalValue()) + result << ':' << option->GetOptionalValue(); + result << ']'; + } else if (option->GetHasArg() == REQUIRED_ARGUMENT) + result << ' ' << metavar; else - Y_ASSERT(option->GetHasArg() == NO_ARGUMENT); + Y_ASSERT(option->GetHasArg() == NO_ARGUMENT); - return result.Str(); + return result.Str(); } - void TOpts::PrintCmdLine(const TStringBuf& program, IOutputStream& os, const NColorizer::TColors& colors) const { + void TOpts::PrintCmdLine(const TStringBuf& program, IOutputStream& os, const NColorizer::TColors& colors) const { os << colors.BoldColor() << "Usage" << colors.OldColor() << ": "; if (CustomUsage) { os << CustomUsage; } else { os << program << " "; } - if (CustomCmdLineDescr) { - os << CustomCmdLineDescr << Endl; - return; + if (CustomCmdLineDescr) { + os << CustomCmdLineDescr << Endl; + return; } - os << "[OPTIONS]"; + os << "[OPTIONS]"; ui32 numDescribedFlags = FreeArgSpecs_.empty() ? 0 : FreeArgSpecs_.rbegin()->first + 1; ui32 numArgsToShow = Max(FreeArgsMin_, FreeArgsMax_ == UNLIMITED_ARGS ? numDescribedFlags : FreeArgsMax_); @@ -342,92 +342,92 @@ namespace NLastGetopt { if (isOptional) os << "]"; - } - + } + if (FreeArgsMax_ == UNLIMITED_ARGS) { os << " [" << TrailingArgSpec_.GetTitle(DefaultFreeArgTitle_) << "]..."; } - os << Endl; - } + os << Endl; + } - void TOpts::PrintUsage(const TStringBuf& program, IOutputStream& osIn, const NColorizer::TColors& colors) const { - TStringStream os; + void TOpts::PrintUsage(const TStringBuf& program, IOutputStream& osIn, const NColorizer::TColors& colors) const { + TStringStream os; - if (!Title.empty()) - os << Title << "\n\n"; + if (!Title.empty()) + os << Title << "\n\n"; - PrintCmdLine(program, os, colors); + PrintCmdLine(program, os, colors); - TVector<TString> leftColumn(Opts_.size()); - TVector<size_t> leftColumnSizes(leftColumn.size()); + TVector<TString> leftColumn(Opts_.size()); + TVector<size_t> leftColumnSizes(leftColumn.size()); const size_t kMaxLeftWidth = 25; - size_t leftWidth = 0; - size_t requiredOptionsCount = 0; - NColorizer::TColors disabledColors(false); + size_t leftWidth = 0; + size_t requiredOptionsCount = 0; + NColorizer::TColors disabledColors(false); for (size_t i = 0; i < Opts_.size(); i++) { const TOpt* opt = Opts_[i].Get(); if (opt->IsHidden()) continue; - leftColumn[i] = FormatOption(opt, colors); + leftColumn[i] = FormatOption(opt, colors); size_t leftColumnSize = leftColumn[i].size(); if (colors.IsTTY()) { leftColumnSize -= NColorizer::TotalAnsiEscapeCodeLen(leftColumn[i]); } - leftColumnSizes[i] = leftColumnSize; + leftColumnSizes[i] = leftColumnSize; if (leftColumnSize <= kMaxLeftWidth) { leftWidth = Max(leftWidth, leftColumnSize); } - if (opt->IsRequired()) - requiredOptionsCount++; - } - - const TString leftPadding(leftWidth, ' '); - - for (size_t sectionId = 0; sectionId <= 1; sectionId++) { - bool requiredOptionsSection = (sectionId == 0); - - if (requiredOptionsSection) { - if (requiredOptionsCount == 0) - continue; - os << Endl << colors.BoldColor() << "Required parameters" << colors.OldColor() << ":" << Endl; + if (opt->IsRequired()) + requiredOptionsCount++; + } + + const TString leftPadding(leftWidth, ' '); + + for (size_t sectionId = 0; sectionId <= 1; sectionId++) { + bool requiredOptionsSection = (sectionId == 0); + + if (requiredOptionsSection) { + if (requiredOptionsCount == 0) + continue; + os << Endl << colors.BoldColor() << "Required parameters" << colors.OldColor() << ":" << Endl; } else { - if (requiredOptionsCount == Opts_.size()) - continue; - if (requiredOptionsCount == 0) - os << Endl << colors.BoldColor() << "Options" << colors.OldColor() << ":" << Endl; - else - os << Endl << colors.BoldColor() << "Optional parameters" << colors.OldColor() << ":" << Endl; // optional options would be a tautology + if (requiredOptionsCount == Opts_.size()) + continue; + if (requiredOptionsCount == 0) + os << Endl << colors.BoldColor() << "Options" << colors.OldColor() << ":" << Endl; + else + os << Endl << colors.BoldColor() << "Optional parameters" << colors.OldColor() << ":" << Endl; // optional options would be a tautology } - for (size_t i = 0; i < Opts_.size(); i++) { - const TOpt* opt = Opts_[i].Get(); - - if (opt->IsHidden()) - continue; - if (opt->IsRequired() != requiredOptionsSection) - continue; - - if (leftColumnSizes[i] > leftWidth && !opt->GetHelp().empty()) { + for (size_t i = 0; i < Opts_.size(); i++) { + const TOpt* opt = Opts_[i].Get(); + + if (opt->IsHidden()) + continue; + if (opt->IsRequired() != requiredOptionsSection) + continue; + + if (leftColumnSizes[i] > leftWidth && !opt->GetHelp().empty()) { os << SPad << leftColumn[i] << Endl << SPad << leftPadding << ' '; - } else { - os << SPad << leftColumn[i] << ' '; - if (leftColumnSizes[i] < leftWidth) + } else { + os << SPad << leftColumn[i] << ' '; + if (leftColumnSizes[i] < leftWidth) os << TStringBuf(leftPadding.data(), leftWidth - leftColumnSizes[i]); } TStringBuf help = opt->GetHelp(); while (help && isspace(help.back())) { help.Chop(1); - } + } size_t lastLineLength = 0; bool helpHasParagraphs = false; if (help) { os << Wrap(Wrap_, help, SPad + leftPadding + " ", &lastLineLength, &helpHasParagraphs); } - - if (opt->HasDefaultValue()) { + + if (opt->HasDefaultValue()) { auto quotedDef = QuoteForHelp(opt->GetDefaultValue()); if (helpHasParagraphs) { os << Endl << Endl << SPad << leftPadding << " "; @@ -445,9 +445,9 @@ namespace NLastGetopt { } else { os << "default: " << colors.CyanColor() << quotedDef << colors.OldColor(); } - } - - os << Endl; + } + + os << Endl; if (helpHasParagraphs) { os << Endl; @@ -455,7 +455,7 @@ namespace NLastGetopt { } } - PrintFreeArgsDesc(os, colors); + PrintFreeArgsDesc(os, colors); for (auto& [heading, text] : Sections) { os << Endl << colors.BoldColor() << heading << colors.OldColor() << ":" << Endl; @@ -463,40 +463,40 @@ namespace NLastGetopt { os << SPad << Wrap(Wrap_, text, SPad) << Endl; } - osIn << os.Str(); + osIn << os.Str(); } - void TOpts::PrintUsage(const TStringBuf& program, IOutputStream& os) const { - PrintUsage(program, os, NColorizer::AutoColors(os)); - } + void TOpts::PrintUsage(const TStringBuf& program, IOutputStream& os) const { + PrintUsage(program, os, NColorizer::AutoColors(os)); + } - void TOpts::PrintFreeArgsDesc(IOutputStream& os, const NColorizer::TColors& colors) const { - if (0 == FreeArgsMax_) - return; + void TOpts::PrintFreeArgsDesc(IOutputStream& os, const NColorizer::TColors& colors) const { + if (0 == FreeArgsMax_) + return; - size_t leftFreeWidth = 0; - for (size_t i = 0; i < FreeArgSpecs_.size(); ++i) { - leftFreeWidth = Max(leftFreeWidth, GetFreeArgTitle(i).size()); - } + size_t leftFreeWidth = 0; + for (size_t i = 0; i < FreeArgSpecs_.size(); ++i) { + leftFreeWidth = Max(leftFreeWidth, GetFreeArgTitle(i).size()); + } if (!TrailingArgSpec_.IsDefault()) { leftFreeWidth = Max(leftFreeWidth, TrailingArgSpec_.GetTitle(DefaultFreeArgTitle_).size()); - } + } - leftFreeWidth = Min(leftFreeWidth, size_t(30)); - os << Endl << colors.BoldColor() << "Free args" << colors.OldColor() << ":"; + leftFreeWidth = Min(leftFreeWidth, size_t(30)); + os << Endl << colors.BoldColor() << "Free args" << colors.OldColor() << ":"; - os << " min: " << colors.GreenColor() << FreeArgsMin_ << colors.OldColor() << ","; - os << " max: " << colors.GreenColor(); + os << " min: " << colors.GreenColor() << FreeArgsMin_ << colors.OldColor() << ","; + os << " max: " << colors.GreenColor(); if (FreeArgsMax_ != UNLIMITED_ARGS) { - os << FreeArgsMax_; - } else { - os << "unlimited"; - } + os << FreeArgsMax_; + } else { + os << "unlimited"; + } os << colors.OldColor() << Endl; - const size_t limit = FreeArgSpecs_.empty() ? 0 : FreeArgSpecs_.rbegin()->first; - for (size_t i = 0; i <= limit; ++i) { + const size_t limit = FreeArgSpecs_.empty() ? 0 : FreeArgSpecs_.rbegin()->first; + for (size_t i = 0; i <= limit; ++i) { if (!FreeArgSpecs_.contains(i)) { continue; } @@ -506,7 +506,7 @@ namespace NLastGetopt { os << SPad << colors.GreenColor() << RightPad(title, leftFreeWidth, ' ') << colors.OldColor() << SPad << help << Endl; } - } + } if (FreeArgsMax_ == UNLIMITED_ARGS) { auto title = TrailingArgSpec_.GetTitle(DefaultFreeArgTitle_); @@ -514,6 +514,6 @@ namespace NLastGetopt { os << SPad << colors.GreenColor() << RightPad(title, leftFreeWidth, ' ') << colors.OldColor() << SPad << help << Endl; } - } + } } } diff --git a/library/cpp/getopt/small/last_getopt_opts.h b/library/cpp/getopt/small/last_getopt_opts.h index 825b99c871..f7469ea313 100644 --- a/library/cpp/getopt/small/last_getopt_opts.h +++ b/library/cpp/getopt/small/last_getopt_opts.h @@ -7,14 +7,14 @@ #include <util/generic/map.h> namespace NLastGetopt { - enum EArgPermutation { - REQUIRE_ORDER, - PERMUTE, - RETURN_IN_ORDER, - DEFAULT_ARG_PERMUTATION = PERMUTE - }; - - /** + enum EArgPermutation { + REQUIRE_ORDER, + PERMUTE, + RETURN_IN_ORDER, + DEFAULT_ARG_PERMUTATION = PERMUTE + }; + + /** * NLastGetopt::TOpts is a storage of program options' parse rules. * It contains information about all options, free args, some parsing options * and rules about interaction between options. @@ -34,96 +34,96 @@ namespace NLastGetopt { * - Allowing unknown options * */ - class TOpts { - friend class TOptsParseResult; - friend class TOptsParser; + class TOpts { + friend class TOptsParseResult; + friend class TOptsParser; - public: + public: static constexpr const ui32 UNLIMITED_ARGS = Max<ui32>(); - typedef TVector<TSimpleSharedPtr<TOpt>> TOptsVector; - TOptsVector Opts_; // infomation about named (short and long) options + typedef TVector<TSimpleSharedPtr<TOpt>> TOptsVector; + TOptsVector Opts_; // infomation about named (short and long) options TVector<std::function<void(TStringBuf)>> ArgBindings_; - EArgPermutation ArgPermutation_ = DEFAULT_ARG_PERMUTATION; // determines how to parse positions of named and free options. See information below. - bool AllowSingleDashForLong_ = false; // - bool AllowPlusForLong_ = false; // using '+' instead '--' for long options + EArgPermutation ArgPermutation_ = DEFAULT_ARG_PERMUTATION; // determines how to parse positions of named and free options. See information below. + bool AllowSingleDashForLong_ = false; // + bool AllowPlusForLong_ = false; // using '+' instead '--' for long options - //Allows unknwon options: - bool AllowUnknownCharOptions_ = false; - bool AllowUnknownLongOptions_ = false; + //Allows unknwon options: + bool AllowUnknownCharOptions_ = false; + bool AllowUnknownLongOptions_ = false; ui32 Wrap_ = 80; - private: - ui32 FreeArgsMin_; // minimal number of free args - ui32 FreeArgsMax_; // maximal number of free args + private: + ui32 FreeArgsMin_; // minimal number of free args + ui32 FreeArgsMax_; // maximal number of free args TMap<ui32, TFreeArgSpec> FreeArgSpecs_; // mapping [free arg position] -> [free arg specification] TFreeArgSpec TrailingArgSpec_; // spec for the trailing argument (when arguments are unlimited) TString DefaultFreeArgTitle_ = "ARG"; // title that's used for free args without a title - TString Title; // title of the help string - TString CustomCmdLineDescr; // user defined help string + TString Title; // title of the help string + TString CustomCmdLineDescr; // user defined help string TString CustomUsage; // user defined usage string TVector<std::pair<TString, TString>> Sections; // additional help entries to print after usage - public: - /** + public: + /** * Constructs TOpts from string as in getopt(3) */ - TOpts(const TStringBuf& optstring = TStringBuf()); + TOpts(const TStringBuf& optstring = TStringBuf()); - /** + /** * Constructs TOpts from string as in getopt(3) and * additionally adds help option (for '?') and svn-verstion option (for 'V') */ - static TOpts Default(const TStringBuf& optstring = TStringBuf()) { - TOpts opts(optstring); - opts.AddHelpOption(); - opts.AddVersionOption(); - return opts; - } + static TOpts Default(const TStringBuf& optstring = TStringBuf()) { + TOpts opts(optstring); + opts.AddHelpOption(); + opts.AddVersionOption(); + return opts; + } - /** + /** * Checks correctness of options' descriptions. * Throws TConfException if validation failed. * Check consist of: * -not intersecting of names * -compability of settings, that responsable for freeArgs parsing */ - void Validate() const; + void Validate() const; - /** + /** * Search for the option with given long name * @param name long name for search * @return ptr on result (nullptr if not found) */ - const TOpt* FindLongOption(const TStringBuf& name) const; + const TOpt* FindLongOption(const TStringBuf& name) const; - /** + /** * Search for the option with given short name * @param c short name for search * @return ptr on result (nullptr if not found) */ - const TOpt* FindCharOption(char c) const; + const TOpt* FindCharOption(char c) const; - /** + /** * Search for the option with given long name * @param name long name for search * @return ptr on result (nullptr if not found) */ - TOpt* FindLongOption(const TStringBuf& name); + TOpt* FindLongOption(const TStringBuf& name); - /** + /** * Search for the option with given short name * @param c short name for search * @return ptr on result (nullptr if not found) */ - TOpt* FindCharOption(char c); + TOpt* FindCharOption(char c); - /** + /** * Search for the option with given name * @param name name for search * @return ptr on result (nullptr if not found) @@ -152,57 +152,57 @@ namespace NLastGetopt { * Sets title of the help string * @param title title to set */ - void SetTitle(const TString& title) { - Title = title; - } + void SetTitle(const TString& title) { + Title = title; + } - /** + /** * @return true if there is an option with given long name * * @param name long name for search */ - bool HasLongOption(const TString& name) const { - return FindLongOption(name) != nullptr; - } + bool HasLongOption(const TString& name) const { + return FindLongOption(name) != nullptr; + } - /** + /** * @return true if there is an option with given short name * * @param char short name for search */ - bool HasCharOption(char c) const { - return FindCharOption(c) != nullptr; - } + bool HasCharOption(char c) const { + return FindCharOption(c) != nullptr; + } - /** + /** * Search for the option with given long name * @param name long name for search * @return ref on result (throw exception if not found) */ - const TOpt& GetLongOption(const TStringBuf& name) const; + const TOpt& GetLongOption(const TStringBuf& name) const; - /** + /** * Search for the option with given long name * @param name long name for search * @return ref on result (throw exception if not found) */ - TOpt& GetLongOption(const TStringBuf& name); + TOpt& GetLongOption(const TStringBuf& name); - /** + /** * Search for the option with given short name * @param c short name for search * @return ref on result (throw exception if not found) */ - const TOpt& GetCharOption(char c) const; + const TOpt& GetCharOption(char c) const; - /** + /** * Search for the option with given short name * @param c short name for search * @return ref on result (throw exception if not found) */ - TOpt& GetCharOption(char c); + TOpt& GetCharOption(char c); - /** + /** * Search for the option with given name * @param name name for search * @return ref on result (throw exception if not found) @@ -230,21 +230,21 @@ namespace NLastGetopt { /** * @return true if short options exist */ - bool HasAnyShortOption() const; + bool HasAnyShortOption() const; - /** + /** * @return true if long options exist */ - bool HasAnyLongOption() const; + bool HasAnyLongOption() const; - /** + /** * Creates new [option description (TOpt)] as a copy of given one * @param option source * @return reference for created option */ - TOpt& AddOption(const TOpt& option); + TOpt& AddOption(const TOpt& option); - /** + /** * Creates new free argument handling * @param name name of free arg to show in help * @param target variable address to store parsing result into @@ -265,46 +265,46 @@ namespace NLastGetopt { * * @param optstring source */ - void AddCharOptions(const TStringBuf& optstring); + void AddCharOptions(const TStringBuf& optstring); - /** + /** * Creates new [option description (TOpt)] with given short name and given help string * * @param c short name * @param help help string * @return reference for created option */ - TOpt& AddCharOption(char c, const TString& help = "") { - return AddCharOption(c, DEFAULT_HAS_ARG, help); - } + TOpt& AddCharOption(char c, const TString& help = "") { + return AddCharOption(c, DEFAULT_HAS_ARG, help); + } - /** + /** * Creates new [option description (TOpt)] with given short name and given help string * * @param c short name * @param help help string * @return reference for created option */ - TOpt& AddCharOption(char c, EHasArg hasArg, const TString& help = "") { - TOpt option; - option.AddShortName(c); - option.Help(help); - option.HasArg(hasArg); - return AddOption(option); - } + TOpt& AddCharOption(char c, EHasArg hasArg, const TString& help = "") { + TOpt option; + option.AddShortName(c); + option.Help(help); + option.HasArg(hasArg); + return AddOption(option); + } - /** + /** * Creates new [option description (TOpt)] with given long name and given help string * * @param name long name * @param help help string * @return reference for created option */ - TOpt& AddLongOption(const TString& name, const TString& help = "") { - return AddLongOption(0, name, help); - } + TOpt& AddLongOption(const TString& name, const TString& help = "") { + return AddLongOption(0, name, help); + } - /** + /** * Creates new [option description (TOpt)] with given long and short names and given help string * * @param c short name @@ -312,54 +312,54 @@ namespace NLastGetopt { * @param help help string * @return reference for created option */ - TOpt& AddLongOption(char c, const TString& name, const TString& help = "") { - TOpt option; - if (c != 0) - option.AddShortName(c); - option.AddLongName(name); - option.Help(help); - return AddOption(option); - } + TOpt& AddLongOption(char c, const TString& name, const TString& help = "") { + TOpt option; + if (c != 0) + option.AddShortName(c); + option.AddLongName(name); + option.Help(help); + return AddOption(option); + } - /** + /** * Creates new [option description (TOpt)] for help printing, * adds appropriate handler for it * If "help" option already exist, will add given short name to it. * * @param c new short name for help option */ - TOpt& AddHelpOption(char c = '?') { - if (TOpt* o = FindLongOption("help")) { - if (!o->CharIs(c)) - o->AddShortName(c); - return *o; - } - return AddLongOption(c, "help", "print usage") - .HasArg(NO_ARGUMENT) + TOpt& AddHelpOption(char c = '?') { + if (TOpt* o = FindLongOption("help")) { + if (!o->CharIs(c)) + o->AddShortName(c); + return *o; + } + return AddLongOption(c, "help", "print usage") + .HasArg(NO_ARGUMENT) .IfPresentDisableCompletion() - .Handler(&PrintUsageAndExit); + .Handler(&PrintUsageAndExit); } - /** + /** * Creates new [option description (TOpt)] for svn-revision printing, * adds appropriate handler for it. * If "svnversion" option already exist, will add given short name to it. * * @param c new short name for "svnversion" option */ - TOpt& AddVersionOption(char c = 'V') { - if (TOpt* o = FindLongOption("svnrevision")) { - if (!o->CharIs(c)) - o->AddShortName(c); - return *o; - } - return AddLongOption(c, "svnrevision", "print svn version") - .HasArg(NO_ARGUMENT) + TOpt& AddVersionOption(char c = 'V') { + if (TOpt* o = FindLongOption("svnrevision")) { + if (!o->CharIs(c)) + o->AddShortName(c); + return *o; + } + return AddLongOption(c, "svnrevision", "print svn version") + .HasArg(NO_ARGUMENT) .IfPresentDisableCompletion() - .Handler(&PrintVersionAndExit); + .Handler(&PrintVersionAndExit); } - /** + /** * Creates new option for generating completion shell scripts. * * @param command name of command that should be completed (typically corresponds to the executable name). @@ -371,17 +371,17 @@ namespace NLastGetopt { * * @param c new short name for search/create */ - TOpt& CharOption(char c) { - const TOpt* opt = FindCharOption(c); - if (opt != nullptr) { - return const_cast<TOpt&>(*opt); - } else { - AddCharOption(c); - return const_cast<TOpt&>(GetCharOption(c)); - } + TOpt& CharOption(char c) { + const TOpt* opt = FindCharOption(c); + if (opt != nullptr) { + return const_cast<TOpt&>(*opt); + } else { + AddCharOption(c); + return const_cast<TOpt&>(GetCharOption(c)); + } } - /** + /** * Indicate that some options can't appear together. * * Note: this is not transitive. @@ -404,18 +404,18 @@ namespace NLastGetopt { * * @param opt pointer of option to search */ - size_t IndexOf(const TOpt* opt) const; + size_t IndexOf(const TOpt* opt) const; - /** + /** * Replace help string with given * * @param decr new help string */ - void SetCmdLineDescr(const TString& descr) { - CustomCmdLineDescr = descr; - } + void SetCmdLineDescr(const TString& descr) { + CustomCmdLineDescr = descr; + } - /** + /** * Replace usage string with given * * @param usage new usage string @@ -445,12 +445,12 @@ namespace NLastGetopt { * * @param min new value */ - void SetFreeArgsMin(size_t min) { - FreeArgsMin_ = ui32(min); - } + void SetFreeArgsMin(size_t min) { + FreeArgsMin_ = ui32(min); + } - /** + /** * Get current minimal number of free args */ ui32 GetFreeArgsMin() const { @@ -462,12 +462,12 @@ namespace NLastGetopt { * * @param max new value */ - void SetFreeArgsMax(size_t max) { - FreeArgsMax_ = ui32(max); + void SetFreeArgsMax(size_t max) { + FreeArgsMax_ = ui32(max); FreeArgsMax_ = Max<ui32>(FreeArgsMax_, ArgBindings_.size()); - } + } - /** + /** * Get current maximal number of free args */ ui32 GetFreeArgsMax() const { @@ -486,23 +486,23 @@ namespace NLastGetopt { * * @param count new value */ - void SetFreeArgsNum(size_t count) { - FreeArgsMin_ = ui32(count); - FreeArgsMax_ = ui32(count); - } + void SetFreeArgsNum(size_t count) { + FreeArgsMin_ = ui32(count); + FreeArgsMax_ = ui32(count); + } - /** + /** * Set minimal and maximal number of free args * * @param min new value for minimal * @param max new value for maximal */ - void SetFreeArgsNum(size_t min, size_t max) { - FreeArgsMin_ = ui32(min); - FreeArgsMax_ = ui32(max); - } + void SetFreeArgsNum(size_t min, size_t max) { + FreeArgsMin_ = ui32(min); + FreeArgsMax_ = ui32(max); + } - /** + /** * Set title and help string of free argument * * @param pos index of argument @@ -513,7 +513,7 @@ namespace NLastGetopt { */ void SetFreeArgTitle(size_t pos, const TString& title, const TString& help = TString(), bool optional = false); - /** + /** * Get free argument's spec for further modification. */ TFreeArgSpec& GetFreeArgSpec(size_t pos); @@ -556,7 +556,7 @@ namespace NLastGetopt { } /// @} - /** + /** * Get spec for the trailing argument. * * This spec is used to render the last repeated argument when max number of arguments is unlimited. @@ -575,11 +575,11 @@ namespace NLastGetopt { * * @param value new value of the option */ - void SetAllowSingleDashForLong(bool value) { - AllowSingleDashForLong_ = value; - } + void SetAllowSingleDashForLong(bool value) { + AllowSingleDashForLong_ = value; + } - /** + /** * Wrap help text at this number of characters. 0 to disable wrapping. */ void SetWrap(ui32 wrap = 80) { @@ -593,17 +593,17 @@ namespace NLastGetopt { * @param os destination stream * @param colors colorizer */ - void PrintUsage(const TStringBuf& program, IOutputStream& os, const NColorizer::TColors& colors) const; + void PrintUsage(const TStringBuf& program, IOutputStream& os, const NColorizer::TColors& colors) const; - /** + /** * Print usage string * * @param program prefix of result (path to the program) * @param os destination stream */ - void PrintUsage(const TStringBuf& program, IOutputStream& os = Cout) const; - - /** + void PrintUsage(const TStringBuf& program, IOutputStream& os = Cout) const; + + /** * Get list of options in order of definition. */ TVector<const TOpt*> GetOpts() const { @@ -615,29 +615,29 @@ namespace NLastGetopt { } private: - /** + /** * @return argument title of a free argument * * @param pos position of the argument */ TStringBuf GetFreeArgTitle(size_t pos) const; - /** + /** * Print usage helper * * @param program prefix of result (path to the program) * @param os destination stream * @param colors colorizer */ - void PrintCmdLine(const TStringBuf& program, IOutputStream& os, const NColorizer::TColors& colors) const; + void PrintCmdLine(const TStringBuf& program, IOutputStream& os, const NColorizer::TColors& colors) const; - /** + /** * Print usage helper * * @param os destination stream * @param colors colorizer */ - void PrintFreeArgsDesc(IOutputStream& os, const NColorizer::TColors& colors) const; - }; + void PrintFreeArgsDesc(IOutputStream& os, const NColorizer::TColors& colors) const; + }; -} +} diff --git a/library/cpp/getopt/small/last_getopt_parse_result.cpp b/library/cpp/getopt/small/last_getopt_parse_result.cpp index f4b5607a90..ec9e796cf3 100644 --- a/library/cpp/getopt/small/last_getopt_parse_result.cpp +++ b/library/cpp/getopt/small/last_getopt_parse_result.cpp @@ -1,131 +1,131 @@ #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 { + 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(); + } 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::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(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::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(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); + } - 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(); + } - 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_; - } + 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_; - } + 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; - } + 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(); + size_t TOptsParseResult::GetFreeArgCount() const { + return Parser_->Argc_ - GetFreeArgsPos(); } - 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()); - } + 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(); @@ -136,25 +136,25 @@ namespace NLastGetopt { options->ArgBindings_[i](freeArgs[i]); } - } catch (...) { - HandleError(); + } 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 { + 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); + exit(1); } - void TOptsParseResultException::HandleError() const { - throw; - } + void TOptsParseResultException::HandleError() const { + throw; + } } diff --git a/library/cpp/getopt/small/last_getopt_parse_result.h b/library/cpp/getopt/small/last_getopt_parse_result.h index 1ab6f598c9..7f0da9c568 100644 --- a/library/cpp/getopt/small/last_getopt_parse_result.h +++ b/library/cpp/getopt/small/last_getopt_parse_result.h @@ -4,58 +4,58 @@ #include "last_getopt_parser.h" namespace NLastGetopt { - /** + /** * NLastGetopt::TOptParseResult contains all arguments for exactly one TOpt, * that have been fetched during parsing * * The class is a wraper over a vector of nil-terminated strings. */ - class TOptParseResult { - public: - typedef TVector<const char*> TValues; - - public: - TOptParseResult(const TOpt* opt = nullptr) - : Opt_(opt) - { - } - - public: - const TOpt& Opt() const { - return *Opt_; - } - const TOpt* OptPtr() const { - return Opt_; - } - const TValues& Values() const { - return Values_; - } - bool Empty() const { - return Values().empty(); - } - size_t Count() const { - return Values_.size(); - } - void AddValue(const char* val) { - if (nullptr != val) - Values_.push_back(val); - } - const char* DefVal(const char* def = nullptr) const { - return Opt().HasDefaultValue() ? Opt().GetDefaultValue().c_str() : def; - } - const char* Front(const char* def = nullptr) const { - return Empty() ? DefVal(def) : Values().front(); - } - const char* Back(const char* def = nullptr) const { - return Empty() ? DefVal(def) : Values().back(); - } - - private: - const TOpt* Opt_; - TValues Values_; - }; - - /** + class TOptParseResult { + public: + typedef TVector<const char*> TValues; + + public: + TOptParseResult(const TOpt* opt = nullptr) + : Opt_(opt) + { + } + + public: + const TOpt& Opt() const { + return *Opt_; + } + const TOpt* OptPtr() const { + return Opt_; + } + const TValues& Values() const { + return Values_; + } + bool Empty() const { + return Values().empty(); + } + size_t Count() const { + return Values_.size(); + } + void AddValue(const char* val) { + if (nullptr != val) + Values_.push_back(val); + } + const char* DefVal(const char* def = nullptr) const { + return Opt().HasDefaultValue() ? Opt().GetDefaultValue().c_str() : def; + } + const char* Front(const char* def = nullptr) const { + return Empty() ? DefVal(def) : Values().front(); + } + const char* Back(const char* def = nullptr) const { + return Empty() ? DefVal(def) : Values().back(); + } + + private: + const TOpt* Opt_; + TValues Values_; + }; + + /** * NLastGetopt::TOptsParseResult contains result of parsing argc,argv be parser. * * In most common case constructed by argc,argv pair and rules (TOpts). @@ -64,20 +64,20 @@ namespace NLastGetopt { * If error during parsing occures, the program aborts with exit code 1. * Note, that if PERMUTE mode is on, then data, pointed by argv can be changed. */ - class TOptsParseResult { - private: - THolder<TOptsParser> Parser_; //The instance of parser. + class TOptsParseResult { + private: + THolder<TOptsParser> Parser_; //The instance of parser. - // XXX: make argc, argv - typedef TVector<TOptParseResult> TdVec; + // XXX: make argc, argv + typedef TVector<TOptParseResult> TdVec; - TdVec Opts_; //Parsing result for all options, that have been explicitly defined in argc/argv - TdVec OptsDef_; //Parsing result for options, that have been defined by default values only + TdVec Opts_; //Parsing result for all options, that have been explicitly defined in argc/argv + TdVec OptsDef_; //Parsing result for options, that have been defined by default values only - private: - TOptParseResult& OptParseResult(); + private: + TOptParseResult& OptParseResult(); - /** + /** * Searchs for object in given container * * @param vec container @@ -85,49 +85,49 @@ namespace NLastGetopt { * * @retunr ptr on corresponding TOptParseResult */ - static const TOptParseResult* FindParseResult(const TdVec& vec, const TOpt* opt); + static const TOptParseResult* FindParseResult(const TdVec& vec, const TOpt* opt); - protected: - /** + protected: + /** * Performs parsing of comand line arguments. */ - void Init(const TOpts* options, int argc, const char** argv); + void Init(const TOpts* options, int argc, const char** argv); - TOptsParseResult() = default; + TOptsParseResult() = default; - public: - /** + public: + /** * The action in case of parser failure. * Allows to asjust behavior in derived classes. * By default prints error string and aborts the program */ - virtual void HandleError() const; + virtual void HandleError() const; - /** + /** * Constructs object by parsing arguments with given rules * * @param options ptr on parsing rules * @param argc * @param argv */ - TOptsParseResult(const TOpts* options, int argc, const char* argv[]) { - Init(options, argc, argv); - } + TOptsParseResult(const TOpts* options, int argc, const char* argv[]) { + Init(options, argc, argv); + } - /** + /** * Constructs object by parsing arguments with given rules * * @param options ptr on parsing rules * @param argc * @param argv */ - TOptsParseResult(const TOpts* options, int argc, char* argv[]) { - Init(options, argc, const_cast<const char**>(argv)); - } + TOptsParseResult(const TOpts* options, int argc, char* argv[]) { + Init(options, argc, const_cast<const char**>(argv)); + } - virtual ~TOptsParseResult() = default; + virtual ~TOptsParseResult() = default; - /** + /** * Search for TOptParseResult that corresponds to given option (TOpt) * * @param opt ptr on required object @@ -135,9 +135,9 @@ namespace NLastGetopt { * * @return ptr on result */ - const TOptParseResult* FindOptParseResult(const TOpt* opt, bool includeDefault = false) const; + const TOptParseResult* FindOptParseResult(const TOpt* opt, bool includeDefault = false) const; - /** + /** * Search for TOptParseResult that corresponds to given long name * * @param name long name of required object @@ -145,9 +145,9 @@ namespace NLastGetopt { * * @return ptr on result */ - const TOptParseResult* FindLongOptParseResult(const TString& name, bool includeDefault = false) const; + const TOptParseResult* FindLongOptParseResult(const TString& name, bool includeDefault = false) const; - /** + /** * Search for TOptParseResult that corresponds to given short name * * @param c short name of required object @@ -155,14 +155,14 @@ namespace NLastGetopt { * * @return ptr on result */ - const TOptParseResult* FindCharOptParseResult(char c, bool includeDefault = false) const; + const TOptParseResult* FindCharOptParseResult(char c, bool includeDefault = false) const; - /** + /** * @return argv[0] */ - TString GetProgramName() const; + TString GetProgramName() const; - /** + /** * Print usage string. */ void PrintUsage(IOutputStream& os = Cout) const; @@ -170,97 +170,97 @@ namespace NLastGetopt { /** * @return position in [premuted argv] of the first free argument */ - size_t GetFreeArgsPos() const; + size_t GetFreeArgsPos() const; - /** + /** * @return number of fetched free arguments */ - size_t GetFreeArgCount() const; + size_t GetFreeArgCount() const; - /** + /** * @return all fetched free arguments */ - TVector<TString> GetFreeArgs() const; + TVector<TString> GetFreeArgs() const; - /** + /** * @return true if given option exist in results of parsing * * @param opt ptr on required object * @param includeDefault search in results obtained from default values * */ - bool Has(const TOpt* opt, bool includeDefault = false) const; + bool Has(const TOpt* opt, bool includeDefault = false) const; - /** + /** * @return nil terminated string on the last fetched argument of givne option * * @param opt ptr on required object * @param includeDefault search in results obtained from default values */ - const char* Get(const TOpt* opt, bool includeDefault = true) const; + const char* Get(const TOpt* opt, bool includeDefault = true) const; - /** + /** * @return nil terminated string on the last fetched argument of givne option * if option haven't been fetched, given defaultValue will be returned * * @param opt ptr on required object * @param defaultValue */ - const char* GetOrElse(const TOpt* opt, const char* defaultValue) const; + const char* GetOrElse(const TOpt* opt, const char* defaultValue) const; - /** + /** * @return true if given option exist in results of parsing * * @param name long name of required object * @param includeDefault search in results obtained from default values * */ - bool Has(const TString& name, bool includeDefault = false) const; + bool Has(const TString& name, bool includeDefault = false) const; - /** + /** * @return nil terminated string on the last fetched argument of givne option * * @param name long name of required object * @param includeDefault search in results obtained from default values */ - const char* Get(const TString& name, bool includeDefault = true) const; + const char* Get(const TString& name, bool includeDefault = true) const; - /** + /** * @return nil terminated string on the last fetched argument of givne option * if option haven't been fetched, given defaultValue will be returned * * @param name long name of required object * @param defaultValue */ - const char* GetOrElse(const TString& name, const char* defaultValue) const; + const char* GetOrElse(const TString& name, const char* defaultValue) const; - /** + /** * @return true if given option exist in results of parsing * * @param c short name of required object * @param includeDefault search in results obtained from default values * */ - bool Has(char name, bool includeDefault = false) const; + bool Has(char name, bool includeDefault = false) const; - /** + /** * @return nil terminated string on the last fetched argument of givne option * * @param c short name of required object * @param includeDefault search in results obtained from default values */ - const char* Get(char name, bool includeDefault = true) const; + const char* Get(char name, bool includeDefault = true) const; - /** + /** * @return nil terminated string on the last fetched argument of givne option * if option haven't been fetched, given defaultValue will be returned * * @param c short name of required object * @param defaultValue */ - const char* GetOrElse(char name, const char* defaultValue) const; + const char* GetOrElse(char name, const char* defaultValue) const; - /** + /** * for givne option return parsed value of the last fetched argument * if option haven't been fetched, HandleError action is called * @@ -268,18 +268,18 @@ namespace NLastGetopt { * * @return FromString<T>(last feteched argument) */ - template <typename T, typename TKey> - T Get(const TKey opt) const { - const char* value = Get(opt); - try { - return NPrivate::OptFromString<T>(value, opt); - } catch (...) { - HandleError(); - throw; - } + template <typename T, typename TKey> + T Get(const TKey opt) const { + const char* value = Get(opt); + try { + return NPrivate::OptFromString<T>(value, opt); + } catch (...) { + HandleError(); + throw; + } } - /** + /** * for givne option return parsed value of the last fetched argument * if option haven't been fetched, given defaultValue will be returned * @@ -288,34 +288,34 @@ namespace NLastGetopt { * * @return FromString<T>(last feteched argument) */ - template <typename T, typename TKey> - T GetOrElse(const TKey opt, const T& defaultValue) const { - if (Has(opt)) - return Get<T>(opt); - else - return defaultValue; - } - }; - - /** + template <typename T, typename TKey> + T GetOrElse(const TKey opt, const T& defaultValue) const { + if (Has(opt)) + return Get<T>(opt); + else + return defaultValue; + } + }; + + /** * NLastGetopt::TOptsParseResultException contains result of parsing argc,argv be parser. * * Unlike TOptsParseResult, if error during parsing occures, an exception is thrown. * */ - class TOptsParseResultException: public TOptsParseResult { - public: - TOptsParseResultException(const TOpts* options, int argc, const char* argv[]) { - Init(options, argc, argv); - } - TOptsParseResultException(const TOpts* options, int argc, char* argv[]) { - Init(options, argc, const_cast<const char**>(argv)); - } - virtual ~TOptsParseResultException() = default; - void HandleError() const override; - - protected: - TOptsParseResultException() = default; - }; + class TOptsParseResultException: public TOptsParseResult { + public: + TOptsParseResultException(const TOpts* options, int argc, const char* argv[]) { + Init(options, argc, argv); + } + TOptsParseResultException(const TOpts* options, int argc, char* argv[]) { + Init(options, argc, const_cast<const char**>(argv)); + } + virtual ~TOptsParseResultException() = default; + void HandleError() const override; + + protected: + TOptsParseResultException() = default; + }; } diff --git a/library/cpp/getopt/small/last_getopt_parser.cpp b/library/cpp/getopt/small/last_getopt_parser.cpp index 7668b12a03..84d4bd2e33 100644 --- a/library/cpp/getopt/small/last_getopt_parser.cpp +++ b/library/cpp/getopt/small/last_getopt_parser.cpp @@ -5,385 +5,385 @@ #include <util/string/escape.h> namespace NLastGetopt { - void TOptsParser::Init(const TOpts* opts, int argc, const char* argv[]) { - opts->Validate(); + void TOptsParser::Init(const TOpts* opts, int argc, const char* argv[]) { + opts->Validate(); - Opts_ = opts; + Opts_ = opts; - if (argc < 1) + 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; - CurrentValue_ = nullptr; - GotMinusMinus_ = false; - Stopped_ = false; - 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_); - DoSwap(Argv_, that.Argv_); - DoSwap(TempCurrentOpt_, that.TempCurrentOpt_); - DoSwap(ProgramName_, that.ProgramName_); - DoSwap(Pos_, that.Pos_); - DoSwap(Sop_, that.Sop_); - DoSwap(Stopped_, that.Stopped_); - DoSwap(CurrentOpt_, that.CurrentOpt_); - DoSwap(CurrentValue_, that.CurrentValue_); - 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; - CurrentOpt_ = currentOpt; - CurrentValue_ = currentValue; - if (nullptr != currentOpt) - 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_) + Argc_ = argc; + Argv_ = argv; + + ProgramName_ = argv[0]; + + Pos_ = 1; + Sop_ = 0; + CurrentOpt_ = nullptr; + CurrentValue_ = nullptr; + GotMinusMinus_ = false; + Stopped_ = false; + 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_); + DoSwap(Argv_, that.Argv_); + DoSwap(TempCurrentOpt_, that.TempCurrentOpt_); + DoSwap(ProgramName_, that.ProgramName_); + DoSwap(Pos_, that.Pos_); + DoSwap(Sop_, that.Sop_); + DoSwap(Stopped_, that.Stopped_); + DoSwap(CurrentOpt_, that.CurrentOpt_); + DoSwap(CurrentValue_, that.CurrentValue_); + 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; + CurrentOpt_ = currentOpt; + CurrentValue_ = currentValue; + if (nullptr != currentOpt) + 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_) + else if (Argc_ - Pos_ < Opts_->FreeArgsMin_) throw TUsageException() << "required at least " << Opts_->FreeArgsMin_ << " free args"; - else if (Argc_ - Pos_ > Opts_->FreeArgsMax_) + else if (Argc_ - Pos_ > Opts_->FreeArgsMax_) throw TUsageException() << "required at most " << Opts_->FreeArgsMax_ << " free args"; - return false; - } + 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)); + 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_) + if (!Opts_->AllowUnknownCharOptions_) throw TUsageException() << "unknown option '" << EscapeC(arg[sop]) - << "' in '" << arg << "'"; + << "' in '" << arg << "'"; - TempCurrentOpt_.Reset(new TOpt); - TempCurrentOpt_->AddShortName(arg[sop]); + TempCurrentOpt_.Reset(new TOpt); + TempCurrentOpt_->AddShortName(arg[sop]); - sop += 1; + 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); - } + // 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); - } + 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); + 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); - if (!opt) - return ParseUnknownShortOptWithinArg(pos, sop); - p += 1; - if (p == arg.length()) { - return ParseOptParam(opt, pos + 1); - } - if (opt->GetHasArg() == NO_ARGUMENT) { - return Commit(opt, nullptr, pos, p); - } + 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); + if (!opt) + return ParseUnknownShortOptWithinArg(pos, sop); + p += 1; + if (p == arg.length()) { + return ParseOptParam(opt, pos + 1); + } + if (opt->GetHasArg() == NO_ARGUMENT) { + return Commit(opt, nullptr, pos, p); + } 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::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]); - const EIsOpt eio = IsOpt(arg); - Y_ASSERT(EIO_NONE != eio); - if (EIO_DDASH == eio || EIO_PLUS == eio || (Opts_->AllowSingleDashForLong_ || !Opts_->HasAnyShortOption())) { - // long option - bool singleCharPrefix = EIO_DDASH != eio; - arg.Skip(singleCharPrefix ? 1 : 2); - TStringBuf optionName = arg.NextTok('='); - const TOpt* option = Opts_->FindLongOption(optionName); - if (!option) { - if (singleCharPrefix && !arg.IsInited()) { - return ParseShortOptArg(pos); - } else if (Opts_->AllowUnknownLongOptions_) { - return false; - } else { + bool TOptsParser::ParseOptArg(size_t pos) { + Y_ASSERT(pos < Argc_); + TStringBuf arg(Argv_[pos]); + const EIsOpt eio = IsOpt(arg); + Y_ASSERT(EIO_NONE != eio); + if (EIO_DDASH == eio || EIO_PLUS == eio || (Opts_->AllowSingleDashForLong_ || !Opts_->HasAnyShortOption())) { + // long option + bool singleCharPrefix = EIO_DDASH != eio; + arg.Skip(singleCharPrefix ? 1 : 2); + TStringBuf optionName = arg.NextTok('='); + const TOpt* option = Opts_->FindLongOption(optionName); + if (!option) { + if (singleCharPrefix && !arg.IsInited()) { + return ParseShortOptArg(pos); + } else if (Opts_->AllowUnknownLongOptions_) { + return false; + } else { throw TUsageException() << "unknown option '" << optionName - << "' in '" << Argv_[pos] << "'"; - } + << "' in '" << Argv_[pos] << "'"; + } } - if (arg.IsInited()) { - if (option->GetHasArg() == NO_ARGUMENT) + if (arg.IsInited()) { + if (option->GetHasArg() == NO_ARGUMENT) throw TUsageException() << "option " << optionName << " must have no arg"; - return Commit(option, arg, pos + 1, 0); - } - ++pos; - return ParseOptParam(option, pos); - } else { - return ParseShortOptArg(pos); + return Commit(option, arg, pos + 1, 0); + } + ++pos; + 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) { - return Commit(opt, nullptr, pos, 0); - } - if (pos == Argc_) { - if (opt->GetHasArg() == REQUIRED_ARGUMENT) + bool TOptsParser::ParseOptParam(const TOpt* opt, size_t pos) { + Y_ASSERT(opt); + if (opt->GetHasArg() == NO_ARGUMENT) { + return Commit(opt, nullptr, pos, 0); + } + if (pos == Argc_) { + if (opt->GetHasArg() == REQUIRED_ARGUMENT) throw TUsageException() << "option " << opt->ToShortString() << " must have arg"; - return Commit(opt, nullptr, pos, 0); - } - const TStringBuf arg(Argv_[pos]); - if (!arg.StartsWith('-') || opt->GetHasArg() == REQUIRED_ARGUMENT) { - return Commit(opt, arg, pos + 1, 0); - } + return Commit(opt, nullptr, pos, 0); + } + const TStringBuf arg(Argv_[pos]); + if (!arg.StartsWith('-') || opt->GetHasArg() == REQUIRED_ARGUMENT) { + 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()) { - switch (arg[0]) { - default: - break; - case '-': - if ('-' != arg[1]) - eio = EIO_SDASH; - else if (2 < arg.length()) - eio = EIO_DDASH; - break; - case '+': - if (Opts_->AllowPlusForLong_) - eio = EIO_PLUS; - break; - } + TOptsParser::EIsOpt TOptsParser::IsOpt(const TStringBuf& arg) const { + EIsOpt eio = EIO_NONE; + if (1 < arg.length()) { + switch (arg[0]) { + default: + break; + case '-': + if ('-' != arg[1]) + eio = EIO_SDASH; + else if (2 < arg.length()) + eio = EIO_DDASH; + break; + case '+': + if (Opts_->AllowPlusForLong_) + eio = EIO_PLUS; + break; + } } - return eio; + 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); - } + 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); + bool TOptsParser::ParseWithPermutation() { + Y_ASSERT(Sop_ == 0); + Y_ASSERT(Opts_->ArgPermutation_ == PERMUTE); - const size_t p0 = Pos_; + const size_t p0 = Pos_; - size_t pc = Pos_; + size_t pc = Pos_; - for (; pc < Argc_ && EIO_NONE == IsOpt(Argv_[pc]); ++pc) { - // count non-args - } + for (; pc < Argc_ && EIO_NONE == IsOpt(Argv_[pc]); ++pc) { + // count non-args + } - if (pc == Argc_) { - return CommitEndOfOptions(Pos_); - } + if (pc == Argc_) { + return CommitEndOfOptions(Pos_); + } - Pos_ = pc; + Pos_ = pc; - bool r = ParseOptArg(Pos_); + bool r = ParseOptArg(Pos_); Y_ASSERT(r); - while (Pos_ == pc) { - Y_ASSERT(Sop_ > 0); - 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)) { - return ParseOptArg(pos); - } else if (arg == "--") { - if (Opts_->ArgPermutation_ == RETURN_IN_ORDER) { - pos += 1; - if (pos == Argc_) - return CommitEndOfOptions(pos); - GotMinusMinus_ = true; - return Commit(nullptr, Argv_[pos], pos + 1, 0); - } else { - return CommitEndOfOptions(pos + 1); - } - } else if (Opts_->ArgPermutation_ == RETURN_IN_ORDER) { - return Commit(nullptr, arg, pos + 1, 0); - } else if (Opts_->ArgPermutation_ == REQUIRE_ORDER) { - return CommitEndOfOptions(Pos_); + while (Pos_ == pc) { + Y_ASSERT(Sop_ > 0); + 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)) { + return ParseOptArg(pos); + } else if (arg == "--") { + if (Opts_->ArgPermutation_ == RETURN_IN_ORDER) { + pos += 1; + if (pos == Argc_) + return CommitEndOfOptions(pos); + GotMinusMinus_ = true; + return Commit(nullptr, Argv_[pos], pos + 1, 0); + } else { + return CommitEndOfOptions(pos + 1); + } + } else if (Opts_->ArgPermutation_ == RETURN_IN_ORDER) { + return Commit(nullptr, arg, pos + 1, 0); + } else if (Opts_->ArgPermutation_ == REQUIRE_ORDER) { + return CommitEndOfOptions(Pos_); } else { - return ParseWithPermutation(); + return ParseWithPermutation(); } } - bool TOptsParser::Next() { - bool r = false; - - if (OptsDefault_.empty()) { - CurrentOpt_ = nullptr; - TempCurrentOpt_.Destroy(); + bool TOptsParser::Next() { + bool r = false; - CurrentValue_ = nullptr; + if (OptsDefault_.empty()) { + CurrentOpt_ = nullptr; + TempCurrentOpt_.Destroy(); - if (Stopped_) - return false; + CurrentValue_ = nullptr; - TOptsParser copy = *this; + if (Stopped_) + return false; - r = copy.DoNext(); + TOptsParser copy = *this; - Swap(copy); + r = copy.DoNext(); - if (!r) { - Stopped_ = true; - // we are done; check for missing options - Finish(); - } - } + Swap(copy); - if (!r && !OptsDefault_.empty()) { - CurrentOpt_ = OptsDefault_.front(); - CurrentValue_ = CurrentOpt_->GetDefaultValue(); - OptsDefault_.pop_front(); - r = true; + if (!r) { + Stopped_ = true; + // we are done; check for missing options + Finish(); + } } - if (r) { - if (CurOpt()) - CurOpt()->FireHandlers(this); - } - - return r; + 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; + void TOptsParser::Finish() { + const TOpts::TOptsVector& optvec = Opts_->Opts_; + if (optvec.size() == OptsSeen_.size()) + return; - TVector<TString> missingLong; - TVector<char> missingShort; + TVector<TString> missingLong; + TVector<char> missingShort; - TOpts::TOptsVector::const_iterator it; - for (it = optvec.begin(); it != optvec.end(); ++it) { - const TOpt* opt = (*it).Get(); - if (nullptr == opt) - continue; + TOpts::TOptsVector::const_iterator it; + for (it = optvec.begin(); it != optvec.end(); ++it) { + const TOpt* opt = (*it).Get(); + if (nullptr == opt) + continue; if (OptsSeen_.contains(opt)) - continue; - - if (opt->IsRequired()) { - const TOpt::TLongNames& optnames = opt->GetLongNames(); - if (!optnames.empty()) - missingLong.push_back(optnames[0]); - else { - const char ch = opt->GetCharOr0(); - if (0 != ch) - missingShort.push_back(ch); - } - continue; - } - - if (opt->HasDefaultValue()) - OptsDefault_.push_back(opt); + continue; + + if (opt->IsRequired()) { + const TOpt::TLongNames& optnames = opt->GetLongNames(); + if (!optnames.empty()) + missingLong.push_back(optnames[0]); + else { + const char ch = opt->GetCharOr0(); + if (0 != ch) + missingShort.push_back(ch); + } + 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"); - usage << " required:"; - for (size_t i = 0; i != missingLong.size(); ++i) - usage << " --" << missingLong[i]; - for (size_t i = 0; i != missingShort.size(); ++i) - 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)); - } + // 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"); + usage << " required:"; + for (size_t i = 0; i != missingLong.size(); ++i) + usage << " --" << missingLong[i]; + for (size_t i = 0; i != missingShort.size(); ++i) + 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)); + } } diff --git a/library/cpp/getopt/small/last_getopt_parser.h b/library/cpp/getopt/small/last_getopt_parser.h index 2cf8a6c308..6b5c8cbb97 100644 --- a/library/cpp/getopt/small/last_getopt_parser.h +++ b/library/cpp/getopt/small/last_getopt_parser.h @@ -8,85 +8,85 @@ #include <util/generic/list.h> namespace NLastGetopt { - /** + /** * NLastGetopt::TOptsParser is an implementation of parsing * argv/argv into TOptsParseResult by rules of TOpts. * * The class allows to make complicated handlers. * Note, that if PERMUTE mode is on, then data, pointed by argv can be changed. */ - class TOptsParser { - enum EIsOpt { - EIO_NONE, //is not an option name - EIO_SDASH, //single-dashed ('-c') option name - EIO_DDASH, //double-dashed ("--opt") option name - EIO_PLUS, //plus prefix ("+opt") option name - }; + class TOptsParser { + enum EIsOpt { + EIO_NONE, //is not an option name + EIO_SDASH, //single-dashed ('-c') option name + EIO_DDASH, //double-dashed ("--opt") option name + EIO_PLUS, //plus prefix ("+opt") option name + }; - public: // TODO: make private - const TOpts* Opts_; //rules of parsing + public: // TODO: make private + const TOpts* Opts_; //rules of parsing - // argc/argv pair - size_t Argc_; - const char** Argv_; + // argc/argv pair + size_t Argc_; + const char** Argv_; - private: - //the storage of last unkown options. TODO: can be moved to local-method scope - TCopyPtr<TOpt> TempCurrentOpt_; + private: + //the storage of last unkown options. TODO: can be moved to local-method scope + TCopyPtr<TOpt> TempCurrentOpt_; - public: - //storage of argv[0] - TString ProgramName_; + public: + //storage of argv[0] + TString ProgramName_; - //state of parsing: + //state of parsing: - size_t Pos_; // current element withing argv - size_t Sop_; // current char within arg - bool Stopped_; - bool GotMinusMinus_; //true if "--" have been seen in argv + size_t Pos_; // current element withing argv + size_t Sop_; // current char within arg + bool Stopped_; + bool GotMinusMinus_; //true if "--" have been seen in argv - protected: - const TOpt* CurrentOpt_; // ptr on the last meeted option - TStringBuf CurrentValue_; // the value of the last met argument (corresponding to CurrentOpt_) + protected: + const TOpt* CurrentOpt_; // ptr on the last meeted option + TStringBuf CurrentValue_; // the value of the last met argument (corresponding to CurrentOpt_) - private: - typedef THashSet<const TOpt*> TdOptSet; - TdOptSet OptsSeen_; //the set of options that have been met during parsing + private: + typedef THashSet<const TOpt*> TdOptSet; + TdOptSet OptsSeen_; //the set of options that have been met during parsing - TList<const TOpt*> OptsDefault_; + TList<const TOpt*> OptsDefault_; - private: - void Init(const TOpts* options, int argc, const char* argv[]); - void Init(const TOpts* options, int argc, char* argv[]); + private: + void Init(const TOpts* options, int argc, const char* argv[]); + void Init(const TOpts* options, int argc, char* argv[]); - bool CommitEndOfOptions(size_t pos); - bool Commit(const TOpt* currentOption, const TStringBuf& currentValue, size_t pos, size_t sop); + bool CommitEndOfOptions(size_t pos); + bool Commit(const TOpt* currentOption, const TStringBuf& currentValue, size_t pos, size_t sop); - bool ParseShortOptArg(size_t pos); - bool ParseOptArg(size_t pos); - bool ParseOptParam(const TOpt* opt, size_t pos); - bool ParseUnknownShortOptWithinArg(size_t pos, size_t sop); - bool ParseShortOptWithinArg(size_t pos, size_t sop); - bool ParseWithPermutation(); + bool ParseShortOptArg(size_t pos); + bool ParseOptArg(size_t pos); + bool ParseOptParam(const TOpt* opt, size_t pos); + bool ParseUnknownShortOptWithinArg(size_t pos, size_t sop); + bool ParseShortOptWithinArg(size_t pos, size_t sop); + bool ParseWithPermutation(); - bool DoNext(); - void Finish(); + bool DoNext(); + void Finish(); - EIsOpt IsOpt(const TStringBuf& arg) const; + EIsOpt IsOpt(const TStringBuf& arg) const; - void Swap(TOptsParser& that); + void Swap(TOptsParser& that); - public: - TOptsParser(const TOpts* options, int argc, const char* argv[]) { - Init(options, argc, argv); - } + public: + TOptsParser(const TOpts* options, int argc, const char* argv[]) { + Init(options, argc, argv); + } - TOptsParser(const TOpts* options, int argc, char* argv[]) { - Init(options, argc, argv); - } + TOptsParser(const TOpts* options, int argc, char* argv[]) { + Init(options, argc, argv); + } - /// fetch next argument, false if no more arguments left - bool Next(); + /// fetch next argument, false if no more arguments left + bool Next(); bool Seen(const TOpt* opt) const { return OptsSeen_.contains(opt); @@ -108,47 +108,47 @@ namespace NLastGetopt { } } - const TOpt* CurOpt() const { - return CurrentOpt_; - } - - const char* CurVal() const { - return CurrentValue_.data(); - } - - const TStringBuf& CurValStr() const { - return CurrentValue_; - } - - TStringBuf CurValOrOpt() const { - TStringBuf val(CurValStr()); - if (!val.IsInited() && CurOpt()->HasOptionalValue()) - val = CurOpt()->GetOptionalValue(); - return val; - } - - TStringBuf CurValOrDef(bool useDef = true) const { - TStringBuf val(CurValOrOpt()); - if (!val.IsInited() && useDef && CurOpt()->HasDefaultValue()) - val = CurOpt()->GetDefaultValue(); - return val; - } - - // true if this option was actually specified by the user - bool IsExplicit() const { - return nullptr == CurrentOpt_ || !OptsSeen_.empty(); - } - - bool CurrentIs(const TString& name) const { - return CurOpt()->NameIs(name); - } - - const TString& ProgramName() const { - return ProgramName_; - } - - void PrintUsage(IOutputStream& os = Cout) const; - - void PrintUsage(IOutputStream& os, const NColorizer::TColors& colors) const; - }; -} //namespace NLastGetopt + const TOpt* CurOpt() const { + return CurrentOpt_; + } + + const char* CurVal() const { + return CurrentValue_.data(); + } + + const TStringBuf& CurValStr() const { + return CurrentValue_; + } + + TStringBuf CurValOrOpt() const { + TStringBuf val(CurValStr()); + if (!val.IsInited() && CurOpt()->HasOptionalValue()) + val = CurOpt()->GetOptionalValue(); + return val; + } + + TStringBuf CurValOrDef(bool useDef = true) const { + TStringBuf val(CurValOrOpt()); + if (!val.IsInited() && useDef && CurOpt()->HasDefaultValue()) + val = CurOpt()->GetDefaultValue(); + return val; + } + + // true if this option was actually specified by the user + bool IsExplicit() const { + return nullptr == CurrentOpt_ || !OptsSeen_.empty(); + } + + bool CurrentIs(const TString& name) const { + return CurOpt()->NameIs(name); + } + + const TString& ProgramName() const { + return ProgramName_; + } + + void PrintUsage(IOutputStream& os = Cout) const; + + void PrintUsage(IOutputStream& os, const NColorizer::TColors& colors) const; + }; +} //namespace NLastGetopt diff --git a/library/cpp/getopt/small/last_getopt_support.h b/library/cpp/getopt/small/last_getopt_support.h index 17bed3e614..1f3a852382 100644 --- a/library/cpp/getopt/small/last_getopt_support.h +++ b/library/cpp/getopt/small/last_getopt_support.h @@ -1,178 +1,178 @@ #pragma once -#include <util/string/cast.h> +#include <util/string/cast.h> #include <util/generic/string.h> -#include <util/generic/vector.h> +#include <util/generic/vector.h> #include <util/generic/utility.h> -#include <util/generic/yexception.h> +#include <util/generic/yexception.h> namespace NLastGetopt { - class TOpt; - class TOpts; - class TOptsParser; - class TOptsParseResult; + class TOpt; + class TOpts; + class TOptsParser; + class TOptsParseResult; - /// base of all getopt exceptions - class TException: public yexception { - }; + /// base of all getopt exceptions + class TException: public yexception { + }; /// TOpts configuration is incorrect - class TConfException: public TException { - }; + class TConfException: public TException { + }; /// User passed incorrect arguments, parsing failed /// Note: use `throw TUsageException()` instead of `ythrow TUsageException()` to prevent appearence of stacktrace /// and location of the `ythrow` statment in error messages. - class TUsageException: public TException { - }; - - struct IOptHandler { - virtual void HandleOpt(const TOptsParser* parser) = 0; - virtual ~IOptHandler() = default; - }; - - namespace NPrivate { - template <typename TpFunc> - class THandlerFunctor0 - : public IOptHandler { - TpFunc Func_; - - public: - THandlerFunctor0(TpFunc func) - : Func_(func) - { - } - - void HandleOpt(const TOptsParser*) override { - Func_(); - } - }; - - template <typename TpFunc, typename TpArg = const TOptsParser*> - class THandlerFunctor1 - : public IOptHandler { - TpFunc Func_; - const TpArg Def_; - const bool HasDef_; - - public: - THandlerFunctor1(TpFunc func) - : Func_(func) - , Def_() - , HasDef_(false) - { - } - - template <typename T> - THandlerFunctor1(const TpFunc& func, const T& def) - : Func_(func) - , Def_(def) - , HasDef_(true) - { - } - - void HandleOpt(const TOptsParser* parser) override; - }; - - template <typename TpFunc> - class THandlerFunctor1<TpFunc, const TOptsParser*> - : public IOptHandler { - TpFunc Func_; - - public: - THandlerFunctor1(TpFunc func) - : Func_(func) - { - } - - void HandleOpt(const TOptsParser* parser) override { - Func_(parser); - } - }; - - template <typename T, typename TpVal = T> - class TStoreResultFunctor { - private: - T* Target_; - - public: - TStoreResultFunctor(T* target) - : Target_(target) - { - } - - void operator()(const TpVal& val) { - *Target_ = val; - } - }; - - template <typename TpTarget, typename TpFunc, typename TpVal = TpTarget> - class TStoreMappedResultFunctor { - private: - TpTarget* Target_; - const TpFunc Func_; - - public: - TStoreMappedResultFunctor(TpTarget* target, const TpFunc& func) - : Target_(target) - , Func_(func) - { - } - - void operator()(const TpVal& val) { - *Target_ = Func_(val); - } - }; - - template <typename T, typename TpVal = T> - class TStoreValueFunctor { - T* Target; - const TpVal Value; - - public: - template <typename TpArg> - TStoreValueFunctor(T* target, const TpArg& value) - : Target(target) - , Value(value) - { - } - - void operator()(const TOptsParser*) { - *Target = Value; - } - }; - - TString OptToString(char c); - TString OptToString(const TString& longOption); - TString OptToString(const TOpt* opt); - - template <typename T> - inline T OptFromStringImpl(const TStringBuf& value) { - return FromString<T>(value); + class TUsageException: public TException { + }; + + struct IOptHandler { + virtual void HandleOpt(const TOptsParser* parser) = 0; + virtual ~IOptHandler() = default; + }; + + namespace NPrivate { + template <typename TpFunc> + class THandlerFunctor0 + : public IOptHandler { + TpFunc Func_; + + public: + THandlerFunctor0(TpFunc func) + : Func_(func) + { + } + + void HandleOpt(const TOptsParser*) override { + Func_(); + } + }; + + template <typename TpFunc, typename TpArg = const TOptsParser*> + class THandlerFunctor1 + : public IOptHandler { + TpFunc Func_; + const TpArg Def_; + const bool HasDef_; + + public: + THandlerFunctor1(TpFunc func) + : Func_(func) + , Def_() + , HasDef_(false) + { + } + + template <typename T> + THandlerFunctor1(const TpFunc& func, const T& def) + : Func_(func) + , Def_(def) + , HasDef_(true) + { + } + + void HandleOpt(const TOptsParser* parser) override; + }; + + template <typename TpFunc> + class THandlerFunctor1<TpFunc, const TOptsParser*> + : public IOptHandler { + TpFunc Func_; + + public: + THandlerFunctor1(TpFunc func) + : Func_(func) + { + } + + void HandleOpt(const TOptsParser* parser) override { + Func_(parser); + } + }; + + template <typename T, typename TpVal = T> + class TStoreResultFunctor { + private: + T* Target_; + + public: + TStoreResultFunctor(T* target) + : Target_(target) + { + } + + void operator()(const TpVal& val) { + *Target_ = val; + } + }; + + template <typename TpTarget, typename TpFunc, typename TpVal = TpTarget> + class TStoreMappedResultFunctor { + private: + TpTarget* Target_; + const TpFunc Func_; + + public: + TStoreMappedResultFunctor(TpTarget* target, const TpFunc& func) + : Target_(target) + , Func_(func) + { + } + + void operator()(const TpVal& val) { + *Target_ = Func_(val); + } + }; + + template <typename T, typename TpVal = T> + class TStoreValueFunctor { + T* Target; + const TpVal Value; + + public: + template <typename TpArg> + TStoreValueFunctor(T* target, const TpArg& value) + : Target(target) + , Value(value) + { + } + + void operator()(const TOptsParser*) { + *Target = Value; + } + }; + + TString OptToString(char c); + TString OptToString(const TString& longOption); + TString OptToString(const TOpt* opt); + + template <typename T> + inline T OptFromStringImpl(const TStringBuf& value) { + return FromString<T>(value); } - template <> - inline TStringBuf OptFromStringImpl<TStringBuf>(const TStringBuf& value) { - return value; - } - - template <> - inline const char* OptFromStringImpl<const char*>(const TStringBuf& value) { - return value.data(); - } - - template <typename T, typename TSomeOpt> - T OptFromString(const TStringBuf& value, const TSomeOpt opt) { - try { - return OptFromStringImpl<T>(value); - } catch (...) { + template <> + inline TStringBuf OptFromStringImpl<TStringBuf>(const TStringBuf& value) { + return value; + } + + template <> + inline const char* OptFromStringImpl<const char*>(const TStringBuf& value) { + return value.data(); + } + + template <typename T, typename TSomeOpt> + T OptFromString(const TStringBuf& value, const TSomeOpt opt) { + try { + return OptFromStringImpl<T>(value); + } catch (...) { throw TUsageException() << "failed to parse opt " << OptToString(opt) << " value " << TString(value).Quote() << ": " << CurrentExceptionMessage(); - } - } - - // wrapper of FromString<T> that prints nice message about option used - template <typename T, typename TSomeOpt> - T OptFromString(const TStringBuf& value, const TSomeOpt opt); - - } -} + } + } + + // wrapper of FromString<T> that prints nice message about option used + template <typename T, typename TSomeOpt> + T OptFromString(const TStringBuf& value, const TSomeOpt opt); + + } +} diff --git a/library/cpp/getopt/small/modchooser.cpp b/library/cpp/getopt/small/modchooser.cpp index 2fa5cfd070..4ae8c90dae 100644 --- a/library/cpp/getopt/small/modchooser.cpp +++ b/library/cpp/getopt/small/modchooser.cpp @@ -6,7 +6,7 @@ #include <library/cpp/colorizer/colors.h> -#include <util/stream/output.h> +#include <util/stream/output.h> #include <util/stream/format.h> #include <util/generic/yexception.h> #include <util/generic/ptr.h> diff --git a/library/cpp/getopt/small/modchooser.h b/library/cpp/getopt/small/modchooser.h index 0a8de6d50b..8717acdd54 100644 --- a/library/cpp/getopt/small/modchooser.h +++ b/library/cpp/getopt/small/modchooser.h @@ -2,7 +2,7 @@ #include "last_getopt_opts.h" -#include <util/generic/map.h> +#include <util/generic/map.h> #include <util/generic/string.h> #include <util/generic/vector.h> @@ -19,7 +19,7 @@ using TMainFunctionRawPtr = int (*)(const int argc, const char** argv); //! Mode class with vector of cli arguments. class TMainClassV { public: - virtual int operator()(const TVector<TString>& argv) = 0; + virtual int operator()(const TVector<TString>& argv) = 0; virtual ~TMainClassV() = default; }; @@ -45,7 +45,7 @@ class TModChooser { public: TModChooser(); ~TModChooser(); - + public: void AddMode(const TString& mode, TMainFunctionRawPtr func, const TString& description, bool hidden = false, bool noCompletion = false); void AddMode(const TString& mode, TMainFunctionRawPtrV func, const TString& description, bool hidden = false, bool noCompletion = false); @@ -98,7 +98,7 @@ public: int Run(int argc, const char** argv) const; //! Run appropriate mode. Same as Run(const int, const char**) - int Run(const TVector<TString>& argv) const; + int Run(const TVector<TString>& argv) const; void PrintHelp(const TString& progName) const; diff --git a/library/cpp/getopt/small/opt.cpp b/library/cpp/getopt/small/opt.cpp index 744501765c..36b083ce2a 100644 --- a/library/cpp/getopt/small/opt.cpp +++ b/library/cpp/getopt/small/opt.cpp @@ -1,13 +1,13 @@ -#include "opt.h" - -#include <util/system/progname.h> +#include "opt.h" +#include <util/system/progname.h> + #include <ctype.h> using namespace NLastGetopt; namespace { - struct TOptsNoDefault: public TOpts { + struct TOptsNoDefault: public TOpts { TOptsNoDefault(const TStringBuf& optstring = TStringBuf()) : TOpts(optstring) { @@ -48,7 +48,7 @@ Opt::Opt(int argc, char* argv[], const char* optString, const Ion* longOptions, } 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); + Init(argc, (char**)argv, optString, longOptions, longOnly, isOpen); } int Opt::Get() { @@ -58,7 +58,7 @@ int Opt::Get() { int Opt::Get(int* longOptionIndex) { if (GotError_) return EOF; - + Arg = nullptr; try { @@ -67,12 +67,12 @@ int Opt::Get(int* longOptionIndex) { if (!r) { return EOF; } else { - Arg = (char*)OptsParser_->CurVal(); + Arg = (char*)OptsParser_->CurVal(); if (!OptsParser_->CurOpt()) { // possible if RETURN_IN_ORDER return 1; } else { - const Ion* ion = (const Ion*)OptsParser_->CurOpt()->UserValue(); + const Ion* ion = (const Ion*)OptsParser_->CurOpt()->UserValue(); if (longOptionIndex) { *longOptionIndex = int(ion - Ions_); } @@ -100,20 +100,20 @@ 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; +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; } diff --git a/library/cpp/getopt/small/opt.h b/library/cpp/getopt/small/opt.h index ecb57439bc..1bbd3811a3 100644 --- a/library/cpp/getopt/small/opt.h +++ b/library/cpp/getopt/small/opt.h @@ -1,8 +1,8 @@ #pragma once -#include "last_getopt.h" - -#include <util/generic/ptr.h> +#include "last_getopt.h" + +#include <util/generic/ptr.h> #include <util/generic/noncopyable.h> // implementation of Opt class using last getopt @@ -54,20 +54,20 @@ */ #define OPT_RETURN_IN_ORDER "-" -#define OPT_REQUIRE_ORDER "+" -#define OPT_DONT_STORE_ARG ((void*)0) +#define OPT_REQUIRE_ORDER "+" +#define OPT_DONT_STORE_ARG ((void*)0) -class Opt : TNonCopyable { +class Opt : TNonCopyable { public: - enum HasArg { WithoutArg, - WithArg, - PossibleArg }; + enum HasArg { WithoutArg, + WithArg, + PossibleArg }; struct Ion { - const char* name; - HasArg has_arg; - int* flag; - int val; + const char* name; + HasArg has_arg; + int* flag; + int val; }; private: @@ -75,7 +75,7 @@ private: THolder<NLastGetopt::TOptsParser> OptsParser_; const Ion* Ions_; bool GotError_; - + void Init(int argc, char* argv[], const char* optString, const Ion* longOptions = nullptr, bool longOnly = false, bool isOpen = false); public: @@ -89,19 +89,19 @@ public: return Get(); } - const char* GetArg() const { - return Arg; - } + const char* GetArg() const { + return Arg; + } TVector<TString> GetFreeArgs() const { return NLastGetopt::TOptsParseResult(&*Opts_, GetArgC(), GetArgV()).GetFreeArgs(); } // obsolete, use GetArg() instead - char* Arg; /* option argument if any or NULL */ + char* Arg; /* option argument if any or NULL */ - int Ind; /* command line index */ - bool Err; /* flag to print error messages */ + int Ind; /* command line index */ + bool Err; /* flag to print error messages */ int GetArgC() const; const char** GetArgV() const; @@ -111,32 +111,32 @@ public: // call before getopt. returns non-negative int, removing it from arguments (not found: -1) // Example: returns 11 for "progname -11abc", -1 for "progname -a11" -int opt_get_number(int& argc, char* argv[]); - -#define OPTION_HANDLING_PROLOG \ - { \ - int optlet; \ - while (EOF != (optlet = opt.Get())) { \ - switch (optlet) { -#define OPTION_HANDLING_PROLOG_ANON(S) \ - { \ - Opt opt(argc, argv, (S)); \ - int optlet; \ - while (EOF != (optlet = opt.Get())) { \ - switch (optlet) { -#define OPTION_HANDLE_BEGIN(opt) case opt: { -#define OPTION_HANDLE_END \ - } \ - break; +int opt_get_number(int& argc, char* argv[]); + +#define OPTION_HANDLING_PROLOG \ + { \ + int optlet; \ + while (EOF != (optlet = opt.Get())) { \ + switch (optlet) { +#define OPTION_HANDLING_PROLOG_ANON(S) \ + { \ + Opt opt(argc, argv, (S)); \ + int optlet; \ + while (EOF != (optlet = opt.Get())) { \ + switch (optlet) { +#define OPTION_HANDLE_BEGIN(opt) case opt: { +#define OPTION_HANDLE_END \ + } \ + break; #define OPTION_HANDLE(opt, handle) \ - OPTION_HANDLE_BEGIN(opt) \ - handle; \ - OPTION_HANDLE_END - -#define OPTION_HANDLING_EPILOG \ - default: \ - ythrow yexception() << "unknown optlet"; \ - } \ - } \ - } + OPTION_HANDLE_BEGIN(opt) \ + handle; \ + OPTION_HANDLE_END + +#define OPTION_HANDLING_EPILOG \ + default: \ + ythrow yexception() << "unknown optlet"; \ + } \ + } \ + } diff --git a/library/cpp/getopt/small/opt2.cpp b/library/cpp/getopt/small/opt2.cpp index 0cdc774e78..66a17e2e5d 100644 --- a/library/cpp/getopt/small/opt2.cpp +++ b/library/cpp/getopt/small/opt2.cpp @@ -1,21 +1,21 @@ -#include "opt2.h" - -#include <util/generic/hash.h> -#include <util/generic/utility.h> +#include "opt2.h" + +#include <util/generic/hash.h> +#include <util/generic/utility.h> #include <util/generic/yexception.h> #include <util/str_stl.h> -#include <stdio.h> -#include <errno.h> -#include <ctype.h> - +#include <stdio.h> +#include <errno.h> +#include <ctype.h> + void Opt2::Clear() { Specs.clear(); memset(SpecsMap, 0, sizeof(SpecsMap)); Pos.clear(); } -void Opt2::Init(int argc, char* const* argv, const char* optspec, IntRange free_args_num, const char* long_alias) { +void Opt2::Init(int argc, char* const* argv, const char* optspec, IntRange free_args_num, const char* long_alias) { Clear(); Argc = argc; Argv = argv; @@ -29,7 +29,7 @@ void Opt2::Init(int argc, char* const* argv, const char* optspec, IntRange free_ BadPosCount = HasErrors = true; } -void Opt2::EatArgv(const char* optspec, const char* long_alias) { +void Opt2::EatArgv(const char* optspec, const char* long_alias) { // some flags bool require_order = false; if (*optspec == '+') { @@ -39,11 +39,11 @@ void Opt2::EatArgv(const char* optspec, const char* long_alias) { if (*optspec == '-') ythrow yexception() << "Flag '-' can not be used in Opt2's optspec"; // step 1 - parse optspec - for (const char* s = optspec; *s; s++) { + for (const char* s = optspec; *s; s++) { if (SpecsMap[(ui8)*s]) - ythrow yexception() << "Symbol '" << *s << "' is met twice in Opt2's optspec"; + ythrow yexception() << "Symbol '" << *s << "' is met twice in Opt2's optspec"; if (*s == '?' || *s == '-') - ythrow yexception() << "Opt2: Symbol '" << *s << "' can not be used in optspec because it is reserved"; + ythrow yexception() << "Opt2: Symbol '" << *s << "' can not be used in optspec because it is reserved"; Specs.push_back(Opt2Param()); SpecsMap[(ui8)*s] = (ui8)Specs.size(); // actual index + 1 Specs.back().opt = *s; @@ -59,27 +59,27 @@ void Opt2::EatArgv(const char* optspec, const char* long_alias) { // with single short option (extend it if you really need). THashMap<const char*, char> long2short; long2short["help"] = '?'; - long_alias = long_alias ? long_alias : ""; + long_alias = long_alias ? long_alias : ""; alias_copy = long_alias; - for (char* s = alias_copy.begin(); s && *s;) { - char* eq = strchr(s, '='); - char* comma = strchr(s, ','); - if (comma) - *comma = 0; + for (char* s = alias_copy.begin(); s && *s;) { + char* eq = strchr(s, '='); + char* comma = strchr(s, ','); + if (comma) + *comma = 0; if (!eq || (comma && comma < eq)) - ythrow yexception() << "Opt2, long_alias: '=' is expected after " << s; + ythrow yexception() << "Opt2, long_alias: '=' is expected after " << s; *eq++ = 0; if (!*eq || eq[1]) - ythrow yexception() << "Opt2, long_alias: single letter must be assigned to " << s; + ythrow yexception() << "Opt2, long_alias: single letter must be assigned to " << s; if (!SpecsMap[(ui8)*eq]) - ythrow yexception() << "Opt2, long_alias: trying to assign unknown option '" << *eq << "' to " << s; - Opt2Param& p = Specs[SpecsMap[(ui8)*eq] - 1]; + ythrow yexception() << "Opt2, long_alias: trying to assign unknown option '" << *eq << "' to " << s; + Opt2Param& p = Specs[SpecsMap[(ui8)*eq] - 1]; // If several long options aliased to some letter, only last one is shown in usage p.LongOptName = s; if (long2short.find(s) != long2short.end()) - ythrow yexception() << "Opt2, long_alias: " << s << " specified twice"; + ythrow yexception() << "Opt2, long_alias: " << s << " specified twice"; long2short[s] = *eq; - s = comma ? comma + 1 : nullptr; + s = comma ? comma + 1 : nullptr; } if (Argc < 1) { @@ -96,7 +96,7 @@ void Opt2::EatArgv(const char* optspec, const char* long_alias) { Pos.push_back(Argv[ind]); continue; } - const char* s = Argv[ind] + 1; + const char* s = Argv[ind] + 1; if (*s == '-') { if (!*++s) { // `--' terminates the list of options @@ -104,7 +104,7 @@ void Opt2::EatArgv(const char* optspec, const char* long_alias) { break; } // long option always spans one argv (--switch or --option-name=value) - const char* eq = strchr(s, '='); + const char* eq = strchr(s, '='); TString lname(s, eq ? (size_t)(eq - s) : (size_t)strlen(s)); THashMap<const char*, char>::iterator i = long2short.find(lname.data()); if (i == long2short.end()) { @@ -117,7 +117,7 @@ void Opt2::EatArgv(const char* optspec, const char* long_alias) { HasErrors = true; continue; } - Opt2Param& p = Specs[SpecsMap[(ui8)i->second] - 1]; + Opt2Param& p = Specs[SpecsMap[(ui8)i->second] - 1]; p.IsFound = true; if (p.HasArg && !eq) { HasErrors = true; @@ -142,11 +142,11 @@ void Opt2::EatArgv(const char* optspec, const char* long_alias) { continue; return; } - Opt2Param& p = Specs[SpecsMap[(ui8)*s] - 1]; + Opt2Param& p = Specs[SpecsMap[(ui8)*s] - 1]; p.IsFound = true; if (p.HasArg) { - if (s[1]) - p.ActualValue.push_back(s + 1); + if (s[1]) + p.ActualValue.push_back(s + 1); else { ind++; if (ind == Argc) { @@ -165,10 +165,10 @@ void Opt2::EatArgv(const char* optspec, const char* long_alias) { Pos.push_back(Argv[ind]); } -Opt2Param& Opt2::GetInternal(char opt, const char* defValue, const char* helpUsage, bool requred) { +Opt2Param& Opt2::GetInternal(char opt, const char* defValue, const char* helpUsage, bool requred) { if (!SpecsMap[(ui8)opt]) - ythrow yexception() << "Unspecified option character '" << opt << "' asked from Opt2::Get"; - Opt2Param& p = Specs[SpecsMap[(ui8)opt] - 1]; + ythrow yexception() << "Unspecified option character '" << opt << "' asked from Opt2::Get"; + Opt2Param& p = Specs[SpecsMap[(ui8)opt] - 1]; p.DefValue = defValue; p.HelpUsage = helpUsage; p.IsRequired = requred; @@ -180,49 +180,49 @@ Opt2Param& Opt2::GetInternal(char opt, const char* defValue, const char* helpUsa } // For options with parameters -const char* Opt2::Arg(char opt, const char* help, const char* def, bool required) { - Opt2Param& p = GetInternal(opt, def, help, required); +const char* Opt2::Arg(char opt, const char* help, const char* def, bool required) { + Opt2Param& p = GetInternal(opt, def, help, required); if (!p.HasArg) - ythrow yexception() << "Opt2::Arg called for '" << opt << "' which is an option without argument"; - return p.IsFound ? p.ActualValue.empty() ? nullptr : p.ActualValue.back() : def; + ythrow yexception() << "Opt2::Arg called for '" << opt << "' which is an option without argument"; + return p.IsFound ? p.ActualValue.empty() ? nullptr : p.ActualValue.back() : def; } // For options with parameters -const char* Opt2::Arg(char opt, const char* help, TString def, bool required) { - Opt2Param& p = GetInternal(opt, nullptr, help, required); +const char* Opt2::Arg(char opt, const char* help, TString def, bool required) { + Opt2Param& p = GetInternal(opt, nullptr, help, required); if (!p.HasArg) - ythrow yexception() << "Opt2::Arg called for '" << opt << "' which is an option without argument"; + ythrow yexception() << "Opt2::Arg called for '" << opt << "' which is an option without argument"; p.DefValueStr = def; p.DefValue = p.DefValueStr.begin(); - return p.IsFound ? p.ActualValue.empty() ? nullptr : p.ActualValue.back() : p.DefValue; + return p.IsFound ? p.ActualValue.empty() ? nullptr : p.ActualValue.back() : p.DefValue; } // Options with parameters that can be specified several times -const TVector<const char*>& Opt2::MArg(char opt, const char* help) { - Opt2Param& p = GetInternal(opt, nullptr, help, false); +const TVector<const char*>& Opt2::MArg(char opt, const char* help) { + Opt2Param& p = GetInternal(opt, nullptr, help, false); p.MultipleUse = true; if (!p.HasArg) - ythrow yexception() << "Opt2::Arg called for '" << opt << "' which is an option without argument"; + ythrow yexception() << "Opt2::Arg called for '" << opt << "' which is an option without argument"; return p.ActualValue; } /// For options w/o parameters -bool Opt2::Has(char opt, const char* help) { - Opt2Param& p = GetInternal(opt, nullptr, help, false); +bool Opt2::Has(char opt, const char* help) { + Opt2Param& p = GetInternal(opt, nullptr, help, false); if (p.HasArg) - ythrow yexception() << "Opt2::Has called for '" << opt << "' which is an option with argument"; + ythrow yexception() << "Opt2::Has called for '" << opt << "' which is an option with argument"; return p.IsFound; } // Get() + strtol, may set up HasErrors -long Opt2::Int(char opt, const char* help, long def, bool required) { - Opt2Param& p = GetInternal(opt, (char*)(uintptr_t)def, help, required); +long Opt2::Int(char opt, const char* help, long def, bool required) { + Opt2Param& p = GetInternal(opt, (char*)(uintptr_t)def, help, required); if (!p.HasArg) - ythrow yexception() << "Opt2::Int called for '" << opt << "' which is an option without argument"; + ythrow yexception() << "Opt2::Int called for '" << opt << "' which is an option without argument"; p.IsNumeric = true; if (!p.IsFound || p.ActualValue.empty() || !p.ActualValue.back()) return def; - char* e; + char* e; long rv = strtol(p.ActualValue.back(), &e, 10); if (e == p.ActualValue.back() || *e) { OptionWrongArg = opt; @@ -232,14 +232,14 @@ long Opt2::Int(char opt, const char* help, long def, bool required) { } // Get() + strtoul, may set up HasErrors -unsigned long Opt2::UInt(char opt, const char* help, unsigned long def, bool required) { - Opt2Param& p = GetInternal(opt, (char*)(uintptr_t)def, help, required); +unsigned long Opt2::UInt(char opt, const char* help, unsigned long def, bool required) { + Opt2Param& p = GetInternal(opt, (char*)(uintptr_t)def, help, required); if (!p.HasArg) - ythrow yexception() << "Opt2::UInt called for '" << opt << "' which is an option without argument"; + ythrow yexception() << "Opt2::UInt called for '" << opt << "' which is an option without argument"; p.IsNumeric = true; if (!p.IsFound || p.ActualValue.empty() || !p.ActualValue.back()) return def; - char* e; + char* e; unsigned long rv = strtoul(p.ActualValue.back(), &e, 10); if (e == p.ActualValue.back() || *e) { OptionWrongArg = opt; @@ -251,14 +251,14 @@ unsigned long Opt2::UInt(char opt, const char* help, unsigned long def, bool req // Add user defined error message and set error flag void Opt2::AddError(const char* message) { HasErrors = true; - if (message) + if (message) UserErrorMessages.push_back(message); } -int Opt2::AutoUsage(const char* free_arg_names) { +int Opt2::AutoUsage(const char* free_arg_names) { if (!HasErrors) return 0; - FILE* where = UnknownOption == '?' ? stdout : stderr; + FILE* where = UnknownOption == '?' ? stdout : stderr; char req_str[256], nreq_str[256]; int req = 0, nreq = 0; for (int n = 0; n < (int)Specs.size(); n++) @@ -267,11 +267,11 @@ int Opt2::AutoUsage(const char* free_arg_names) { else nreq_str[nreq++] = Specs[n].opt; req_str[req] = 0, nreq_str[nreq] = 0; - const char* prog = strrchr(Argv[0], LOCSLASH_C); - prog = prog ? prog + 1 : Argv[0]; - fprintf(where, "Usage: %s%s%s%s%s%s%s%s\n", prog, req ? " -" : "", req_str, - nreq ? " [-" : "", nreq_str, nreq ? "]" : "", - free_arg_names && *free_arg_names ? " " : "", free_arg_names); + const char* prog = strrchr(Argv[0], LOCSLASH_C); + prog = prog ? prog + 1 : Argv[0]; + fprintf(where, "Usage: %s%s%s%s%s%s%s%s\n", prog, req ? " -" : "", req_str, + nreq ? " [-" : "", nreq_str, nreq ? "]" : "", + free_arg_names && *free_arg_names ? " " : "", free_arg_names); for (auto& spec : Specs) { const char* hlp = !spec.HelpUsage.empty() ? spec.HelpUsage.data() : spec.HasArg ? "<arg>" : ""; if (!spec.HasArg || spec.IsRequired) @@ -305,7 +305,7 @@ int Opt2::AutoUsage(const char* free_arg_names) { return UnknownOption == '?' ? 1 : 2; } -void Opt2::AutoUsageErr(const char* free_arg_names) { +void Opt2::AutoUsageErr(const char* free_arg_names) { if (AutoUsage(free_arg_names)) exit(1); } @@ -314,15 +314,15 @@ void Opt2::AutoUsageErr(const char* free_arg_names) { // TODO: convert it to unittest bool opt2_ut_fail = false, opt_ut_verbose = false; -const char* ut_optspec; -int ut_real(TString args, bool err_exp, const char* A_exp, int b_exp, bool a_exp, const char* p1_exp, const char* p2_exp) { - char* argv[32]; +const char* ut_optspec; +int ut_real(TString args, bool err_exp, const char* A_exp, int b_exp, bool a_exp, const char* p1_exp, const char* p2_exp) { + char* argv[32]; int argc = sf(' ', argv, args.begin()); Opt2 opt(argc, argv, ut_optspec, 2, "option-1=A,option-2=a,"); - const char* A = opt.Arg('A', "<qqq> - blah"); - int b = opt.Int('b', "<rrr> - blah", 2); - bool a = opt.Has('a', "- blah"); - /*const char *C = */ opt.Arg('C', "<ccc> - blah", 0); + const char* A = opt.Arg('A', "<qqq> - blah"); + int b = opt.Int('b', "<rrr> - blah", 2); + bool a = opt.Has('a', "- blah"); + /*const char *C = */ opt.Arg('C', "<ccc> - blah", 0); if (opt_ut_verbose) opt.AutoUsage(""); @@ -343,7 +343,7 @@ int ut_real(TString args, bool err_exp, const char* A_exp, int b_exp, bool a_exp return false; } -void ut(const char* args, bool err_exp, const char* A_exp, int b_exp, bool a_exp, const char* p1_exp, const char* p2_exp) { +void ut(const char* args, bool err_exp, const char* A_exp, int b_exp, bool a_exp, const char* p1_exp, const char* p2_exp) { if (opt_ut_verbose) fprintf(stderr, "Testing: %s\n", args); if (int rv = ut_real(args, err_exp, A_exp, b_exp, a_exp, p1_exp, p2_exp)) { @@ -355,7 +355,7 @@ void ut(const char* args, bool err_exp, const char* A_exp, int b_exp, bool a_exp } } -int main(int argc, char* argv[]) { +int main(int argc, char* argv[]) { Opt2 opt(argc, argv, "v", 0); opt_ut_verbose = opt.Has('v', "- some verboseness"); opt.AutoUsageErr(""); diff --git a/library/cpp/getopt/small/opt2.h b/library/cpp/getopt/small/opt2.h index 4d9d943237..9a9eb579a8 100644 --- a/library/cpp/getopt/small/opt2.h +++ b/library/cpp/getopt/small/opt2.h @@ -30,11 +30,11 @@ struct Opt2Param { bool IsNumeric; bool IsRequired; bool MultipleUse; - const char* DefValue; + const char* DefValue; TString DefValueStr; TString HelpUsage; TVector<const char*> ActualValue; - const char* LongOptName; + const char* LongOptName; Opt2Param() : HasArg(false) , IsFound(0) @@ -67,45 +67,45 @@ class Opt2 { public: Opt2() = default; - Opt2(int argc, char* const* argv, const char* optspec, IntRange free_args_num = -1, const char* long_alias = nullptr) { + Opt2(int argc, char* const* argv, const char* optspec, IntRange free_args_num = -1, const char* long_alias = nullptr) { Init(argc, argv, optspec, free_args_num, long_alias); } // Init throws exception only in case of incorrect optspec. // In other cases, consult HasErrors or call AutoUsage() - void Init(int argc, char* const* argv, const char* optspec, IntRange free_args_num = -1, const char* long_alias = nullptr); + void Init(int argc, char* const* argv, const char* optspec, IntRange free_args_num = -1, const char* long_alias = nullptr); // In case of incorrect options, constructs and prints Usage text, // usually to stderr (however, to stdout if '-?' switch was used), and returns 1. - int AutoUsage(const char* free_arg_names = ""); + int AutoUsage(const char* free_arg_names = ""); // same as AutoUsage but calls exit(1) instead of error code - void AutoUsageErr(const char* free_arg_names = ""); + void AutoUsageErr(const char* free_arg_names = ""); // For options with parameters - const char* Arg(char opt, const char* helpUsage, const char* defValue, bool required = false); - const char* Arg(char opt, const char* helpUsage) { + const char* Arg(char opt, const char* helpUsage, const char* defValue, bool required = false); + const char* Arg(char opt, const char* helpUsage) { return Arg(opt, helpUsage, nullptr, true); } - const char* Arg(char opt, const char* helpUsage, TString defValue, bool required = false); + const char* Arg(char opt, const char* helpUsage, TString defValue, bool required = false); // Options with parameters that can be specified several times - const TVector<const char*>& MArg(char opt, const char* helpUsage); + const TVector<const char*>& MArg(char opt, const char* helpUsage); // Get() + strtol, may set up HasErrors - long Int(char opt, const char* helpUsage, long defValue, bool required = false); - long Int(char opt, const char* helpUsage) { + long Int(char opt, const char* helpUsage, long defValue, bool required = false); + long Int(char opt, const char* helpUsage) { return Int(opt, helpUsage, 0, true); } // Get() + strtoul, may set up HasErrors - unsigned long UInt(char opt, const char* helpUsage, unsigned long defValue, bool required = false); - unsigned long UInt(char opt, const char* helpUsage) { + unsigned long UInt(char opt, const char* helpUsage, unsigned long defValue, bool required = false); + unsigned long UInt(char opt, const char* helpUsage) { return UInt(opt, helpUsage, 0, true); } // For options w/o parameters - bool Has(char opt, const char* helpUsage); + bool Has(char opt, const char* helpUsage); // Add user defined error message and set error flag void AddError(const char* message = nullptr); @@ -118,7 +118,7 @@ public: private: bool BadPosCount; char UnknownOption; - char* UnknownLongOption; + char* UnknownLongOption; char OptionMissingArg; char OptionWrongArg; char RequiredOptionMissing; @@ -131,7 +131,7 @@ protected: ui8 SpecsMap[256]; TVector<Opt2Param> Specs; TString alias_copy; - void EatArgv(const char* optspec, const char* long_alias); + void EatArgv(const char* optspec, const char* long_alias); void Clear(); - Opt2Param& GetInternal(char opt, const char* defValue, const char* helpUsage, bool required); + Opt2Param& GetInternal(char opt, const char* defValue, const char* helpUsage, bool required); }; diff --git a/library/cpp/getopt/small/posix_getopt.cpp b/library/cpp/getopt/small/posix_getopt.cpp index bd06f3499f..57cc5c66a7 100644 --- a/library/cpp/getopt/small/posix_getopt.cpp +++ b/library/cpp/getopt/small/posix_getopt.cpp @@ -1,7 +1,7 @@ -#include "posix_getopt.h" - -#include <util/generic/ptr.h> - +#include "posix_getopt.h" + +#include <util/generic/ptr.h> + #include <ctype.h> namespace NLastGetopt { @@ -14,8 +14,8 @@ namespace NLastGetopt { static THolder<TOpts> Opts; static THolder<TOptsParser> OptsParser; - int getopt_long_impl(int argc, char* const* argv, const char* optstring, - const struct option* longopts, int* longindex, bool long_only) { + int getopt_long_impl(int argc, char* const* argv, const char* optstring, + const struct option* longopts, int* longindex, bool long_only) { if (!Opts || optreset == 1) { optarg = nullptr; optind = 1; @@ -38,7 +38,7 @@ namespace NLastGetopt { opt->UserValue(o->flag); } - OptsParser.Reset(new TOptsParser(&*Opts, argc, (const char**)argv)); + OptsParser.Reset(new TOptsParser(&*Opts, argc, (const char**)argv)); } optarg = nullptr; @@ -47,10 +47,10 @@ namespace NLastGetopt { if (!OptsParser->Next()) { return -1; } else { - optarg = (char*)OptsParser->CurVal(); + optarg = (char*)OptsParser->CurVal(); optind = (int)OptsParser->Pos_; if (longindex && OptsParser->CurOpt()) - *longindex = (int)Opts->IndexOf(OptsParser->CurOpt()); + *longindex = (int)Opts->IndexOf(OptsParser->CurOpt()); return OptsParser->CurOpt() ? OptsParser->CurOpt()->GetCharOr0() : 1; } } catch (const NLastGetopt::TException&) { @@ -58,13 +58,13 @@ namespace NLastGetopt { } } - int getopt_long(int argc, char* const* argv, const char* optstring, - const struct option* longopts, int* longindex) { + int getopt_long(int argc, char* const* argv, const char* optstring, + const struct option* longopts, int* longindex) { return getopt_long_impl(argc, argv, optstring, longopts, longindex, false); } int getopt_long_only(int argc, char* const* argv, const char* optstring, - const struct option* longopts, int* longindex) { + const struct option* longopts, int* longindex) { return getopt_long_impl(argc, argv, optstring, longopts, longindex, true); } diff --git a/library/cpp/getopt/small/posix_getopt.h b/library/cpp/getopt/small/posix_getopt.h index e6af1e0284..8a8891a1f6 100644 --- a/library/cpp/getopt/small/posix_getopt.h +++ b/library/cpp/getopt/small/posix_getopt.h @@ -25,8 +25,8 @@ namespace NLastGetopt { }; int getopt(int argc, char* const* argv, const char* optstring); - int getopt_long(int argc, char* const* argv, const char* optstring, - const struct option* longopts, int* longindex); + int getopt_long(int argc, char* const* argv, const char* optstring, + const struct option* longopts, int* longindex); int getopt_long_only(int argc, char* const* argv, const char* optstring, - const struct option* longopts, int* longindex); + const struct option* longopts, int* longindex); } diff --git a/library/cpp/getopt/small/ygetopt.cpp b/library/cpp/getopt/small/ygetopt.cpp index 1f52827f74..8952faeeae 100644 --- a/library/cpp/getopt/small/ygetopt.cpp +++ b/library/cpp/getopt/small/ygetopt.cpp @@ -1,108 +1,108 @@ -#include "opt.h" -#include "ygetopt.h" - +#include "opt.h" +#include "ygetopt.h" + #include <util/generic/string.h> #include <util/generic/vector.h> #include <util/generic/yexception.h> - -class TGetOpt::TImpl: public TSimpleRefCount<TImpl> { -public: - inline TImpl(int argc, const char* const* argv, const TString& fmt) - : args(argv, argv + argc) - , format(fmt) - { - if (argc == 0) { - ythrow yexception() << "zero argc"; - } - } - - inline ~TImpl() = default; - - TVector<TString> args; - const TString format; -}; - -class TGetOpt::TIterator::TIterImpl: public TSimpleRefCount<TIterImpl> { -public: - inline TIterImpl(const TGetOpt* parent) - : Args_(parent->Impl_->args) - , ArgsPtrs_(new char*[Args_.size() + 1]) - , Format_(parent->Impl_->format) - , OptLet_(0) - , Arg_(nullptr) - { - for (size_t i = 0; i < Args_.size(); ++i) { - ArgsPtrs_.Get()[i] = Args_[i].begin(); - } - - ArgsPtrs_.Get()[Args_.size()] = nullptr; + +class TGetOpt::TImpl: public TSimpleRefCount<TImpl> { +public: + inline TImpl(int argc, const char* const* argv, const TString& fmt) + : args(argv, argv + argc) + , format(fmt) + { + if (argc == 0) { + ythrow yexception() << "zero argc"; + } + } + + inline ~TImpl() = default; + + TVector<TString> args; + const TString format; +}; + +class TGetOpt::TIterator::TIterImpl: public TSimpleRefCount<TIterImpl> { +public: + inline TIterImpl(const TGetOpt* parent) + : Args_(parent->Impl_->args) + , ArgsPtrs_(new char*[Args_.size() + 1]) + , Format_(parent->Impl_->format) + , OptLet_(0) + , Arg_(nullptr) + { + for (size_t i = 0; i < Args_.size(); ++i) { + ArgsPtrs_.Get()[i] = Args_[i].begin(); + } + + ArgsPtrs_.Get()[Args_.size()] = nullptr; Opt_.Reset(new Opt((int)Args_.size(), ArgsPtrs_.Get(), Format_.data())); - } - - inline ~TIterImpl() = default; - - inline void Next() { - OptLet_ = Opt_->Get(); - Arg_ = Opt_->Arg; - } - - inline char Key() const noexcept { - return (char)OptLet_; - } - - inline const char* Arg() const noexcept { - return Arg_; - } - - inline bool AtEnd() const noexcept { - return OptLet_ == EOF; - } - -private: - TVector<TString> Args_; - TArrayHolder<char*> ArgsPtrs_; - const TString Format_; - THolder<Opt> Opt_; - int OptLet_; - const char* Arg_; -}; - + } + + inline ~TIterImpl() = default; + + inline void Next() { + OptLet_ = Opt_->Get(); + Arg_ = Opt_->Arg; + } + + inline char Key() const noexcept { + return (char)OptLet_; + } + + inline const char* Arg() const noexcept { + return Arg_; + } + + inline bool AtEnd() const noexcept { + return OptLet_ == EOF; + } + +private: + TVector<TString> Args_; + TArrayHolder<char*> ArgsPtrs_; + const TString Format_; + THolder<Opt> Opt_; + int OptLet_; + const char* Arg_; +}; + TGetOpt::TIterator::TIterator() noexcept : Impl_(nullptr) -{ -} - -TGetOpt::TIterator::TIterator(const TGetOpt* parent) - : Impl_(new TIterImpl(parent)) -{ - Next(); -} - -void TGetOpt::TIterator::Next() { - Impl_->Next(); -} - +{ +} + +TGetOpt::TIterator::TIterator(const TGetOpt* parent) + : Impl_(new TIterImpl(parent)) +{ + Next(); +} + +void TGetOpt::TIterator::Next() { + Impl_->Next(); +} + char TGetOpt::TIterator::Key() const noexcept { - return Impl_->Key(); -} - + return Impl_->Key(); +} + bool TGetOpt::TIterator::AtEnd() const noexcept { - if (Impl_.Get()) { - return Impl_->AtEnd(); - } - - return true; -} - + if (Impl_.Get()) { + return Impl_->AtEnd(); + } + + return true; +} + const char* TGetOpt::TIterator::Arg() const noexcept { - if (Impl_.Get()) { - return Impl_->Arg(); - } - + if (Impl_.Get()) { + return Impl_->Arg(); + } + return nullptr; -} - +} + TGetOpt::TGetOpt(int argc, const char* const* argv, const TString& format) - : Impl_(new TImpl(argc, argv, format)) -{ -} + : Impl_(new TImpl(argc, argv, format)) +{ +} diff --git a/library/cpp/getopt/small/ygetopt.h b/library/cpp/getopt/small/ygetopt.h index 615d3dd18e..6f9b92cc79 100644 --- a/library/cpp/getopt/small/ygetopt.h +++ b/library/cpp/getopt/small/ygetopt.h @@ -1,72 +1,72 @@ #pragma once - + #include <util/generic/fwd.h> #include <util/generic/ptr.h> - -class TGetOpt { -public: - class TIterator { - friend class TGetOpt; - - public: - char Key() const noexcept; - const char* Arg() const noexcept; - - inline bool HaveArg() const noexcept { - return Arg(); - } - - inline void operator++() { - Next(); - } - - inline bool operator==(const TIterator& r) const noexcept { - return AtEnd() == r.AtEnd(); - } - - inline bool operator!=(const TIterator& r) const noexcept { - return !(*this == r); - } - - inline TIterator& operator*() noexcept { - return *this; - } - - inline const TIterator& operator*() const noexcept { - return *this; - } - - inline TIterator* operator->() noexcept { - return this; - } - - inline const TIterator* operator->() const noexcept { - return this; - } - - private: - TIterator() noexcept; - TIterator(const TGetOpt* parent); - - void Next(); - bool AtEnd() const noexcept; - - private: - class TIterImpl; - TSimpleIntrusivePtr<TIterImpl> Impl_; - }; - - TGetOpt(int argc, const char* const* argv, const TString& format); - - inline TIterator Begin() const { - return TIterator(this); - } - - inline TIterator End() const noexcept { - return TIterator(); - } - -private: - class TImpl; - TSimpleIntrusivePtr<TImpl> Impl_; -}; + +class TGetOpt { +public: + class TIterator { + friend class TGetOpt; + + public: + char Key() const noexcept; + const char* Arg() const noexcept; + + inline bool HaveArg() const noexcept { + return Arg(); + } + + inline void operator++() { + Next(); + } + + inline bool operator==(const TIterator& r) const noexcept { + return AtEnd() == r.AtEnd(); + } + + inline bool operator!=(const TIterator& r) const noexcept { + return !(*this == r); + } + + inline TIterator& operator*() noexcept { + return *this; + } + + inline const TIterator& operator*() const noexcept { + return *this; + } + + inline TIterator* operator->() noexcept { + return this; + } + + inline const TIterator* operator->() const noexcept { + return this; + } + + private: + TIterator() noexcept; + TIterator(const TGetOpt* parent); + + void Next(); + bool AtEnd() const noexcept; + + private: + class TIterImpl; + TSimpleIntrusivePtr<TIterImpl> Impl_; + }; + + TGetOpt(int argc, const char* const* argv, const TString& format); + + inline TIterator Begin() const { + return TIterator(this); + } + + inline TIterator End() const noexcept { + return TIterator(); + } + +private: + class TImpl; + TSimpleIntrusivePtr<TImpl> Impl_; +}; diff --git a/library/cpp/getopt/ut/last_getopt_ut.cpp b/library/cpp/getopt/ut/last_getopt_ut.cpp index c99a1d053d..0bdfff4f52 100644 --- a/library/cpp/getopt/ut/last_getopt_ut.cpp +++ b/library/cpp/getopt/ut/last_getopt_ut.cpp @@ -1,5 +1,5 @@ #include <library/cpp/getopt/last_getopt.h> - + #include <library/cpp/colorizer/colors.h> #include <library/cpp/testing/unittest/registar.h> @@ -11,14 +11,14 @@ using namespace NLastGetopt; namespace { - struct TOptsNoDefault: public TOpts { + struct TOptsNoDefault: public TOpts { TOptsNoDefault(const TStringBuf& optstring = TStringBuf()) : TOpts(optstring) { } }; - class TOptsParseResultTestWrapper: public TOptsParseResultException { + class TOptsParseResultTestWrapper: public TOptsParseResultException { TVector<const char*> Argv_; public: @@ -174,11 +174,11 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { UNIT_ASSERT_EXCEPTION( TOptsParseResultTestWrapper(&opts, V({"cp", "/etc", "/tmp/etc", "verbose", "nosymlink"})), - yexception); + yexception); UNIT_ASSERT_EXCEPTION( TOptsParseResultTestWrapper(&opts, V({"cp"})), - yexception); + yexception); opts.SetFreeArgsNum(2); TOptsParseResultTestWrapper r22(&opts, V({"cp", "/etc", "/var/tmp"})); @@ -347,16 +347,16 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { } Y_UNIT_TEST(TestDuplicatedOptionCrash) { - // this test is broken, cause UNIT_ASSERT(false) always throws - return; - + // this test is broken, cause UNIT_ASSERT(false) always throws + return; + bool exception = false; try { TOpts opts; opts.AddLongOption('x', "one"); opts.AddLongOption('x', "two"); UNIT_ASSERT(false); - } catch (...) { + } catch (...) { // we should go here, duplicating options are forbidden exception = true; } @@ -529,21 +529,21 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { opt_d.Required(); UNIT_ASSERT_EXCEPTION( TOptsParseResultTestWrapper(&opts, V({"cmd"})), - TUsageException); + TUsageException); TOptsParseResultTestWrapper r3(&opts, V({"cmd", "-d11"})); UNIT_ASSERT_VALUES_EQUAL("11", r3.Get('d')); } - class HandlerStoreTrue { - bool* Flag; - + class HandlerStoreTrue { + bool* Flag; + public: - HandlerStoreTrue(bool* flag) + HandlerStoreTrue(bool* flag) : Flag(flag) { } - void operator()() { + void operator()() { *Flag = true; } }; @@ -561,11 +561,11 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { double fval = 0.0; opts.AddLongOption("flag1").RequiredArgument().StoreResult(&uval); opts.AddLongOption("flag2").RequiredArgument().StoreResultT<int>(&uval); - opts.AddLongOption("flag3").RequiredArgument().StoreMappedResult(&fval, (double (*)(double))fabs); - opts.AddLongOption("flag4").RequiredArgument().StoreMappedResult(&fval, (double (*)(double))sqrt); + opts.AddLongOption("flag3").RequiredArgument().StoreMappedResult(&fval, (double (*)(double))fabs); + opts.AddLongOption("flag4").RequiredArgument().StoreMappedResult(&fval, (double (*)(double))sqrt); UNIT_ASSERT_EXCEPTION( TOptsParseResultTestWrapper(&opts, V({"cmd", "--flag3", "-2.0", "--flag1", "-1"})), - yexception); + yexception); UNIT_ASSERT_VALUES_EQUAL(uval, 5u); UNIT_ASSERT_VALUES_EQUAL(fval, 2.0); TOptsParseResultTestWrapper r1(&opts, V({"cmd", "--flag4", "9.0", "--flag2", "-1"})); @@ -580,7 +580,7 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { TString title = TString("Sample ") + TString(prog).Quote() + " application"; opts.SetTitle(title); int argc = 2; - const char* cmd[] = {prog}; + const char* cmd[] = {prog}; TOptsParser parser(&opts, argc, cmd); TStringStream out; parser.PrintUsage(out); @@ -595,7 +595,7 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { const char* prog = "my_program"; TString customDescr = "<FILE|TABLE> USER [OPTIONS]"; int argc = 2; - const char* cmd[] = {prog}; + const char* cmd[] = {prog}; opts.SetCmdLineDescr(customDescr); TOptsParser parser(&opts, argc, cmd); TStringStream out; @@ -615,7 +615,7 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { opts.SetFreeArgTitle(0, "first_free_arg", "help"); opts.SetFreeArgTitle(2, "second_free_arg"); opts.AddSection("Section", "Section\n text"); - const char* cmd[] = {prog}; + const char* cmd[] = {prog}; TOptsParser parser(&opts, Y_ARRAY_SIZE(cmd), cmd); TStringStream out; NColorizer::TColors colors(true); @@ -663,12 +663,12 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { for (bool withColors : withColorsOpt) { TOpts opts; const char* prog = "my_program"; - opts.AddLongOption("option", "description 1").Required(); // long option - opts.AddLongOption('o', "other", "description 2"); // char and long option - opts.AddCharOption('d', "description 3").RequiredArgument("DD"); // char option + opts.AddLongOption("option", "description 1").Required(); // long option + opts.AddLongOption('o', "other", "description 2"); // char and long option + opts.AddCharOption('d', "description 3").RequiredArgument("DD"); // char option opts.AddCharOption('s', "description 4\ndescription 5\ndescription 6"); // multiline desc opts.AddLongOption('l', "very_very_very_loooong_ooooption", "description 7").RequiredArgument("LONG_ARGUMENT"); - const char* cmd[] = {prog}; + const char* cmd[] = {prog}; TOptsParser parser(&opts, Y_ARRAY_SIZE(cmd), cmd); TStringStream out; @@ -730,7 +730,7 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { TStringBuilder keyvals; TOptsNoDefault opts; - opts.AddLongOption("set").KVHandler([&keyvals](TString k, TString v) { keyvals << k << ":" << v << ","; }); + opts.AddLongOption("set").KVHandler([&keyvals](TString k, TString v) { keyvals << k << ":" << v << ","; }); TOptsParseResultTestWrapper r(&opts, V({"cmd", "--set", "x=1", "--set", "y=2", "--set=z=3"})); @@ -740,7 +740,7 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { Y_UNIT_TEST(TestEasySetup) { TEasySetup opts; bool flag = false; - opts('v', "version", "print version information")('a', "abstract", "some abstract param", true)('b', "buffer", "SIZE", "some param with argument")('c', "count", "SIZE", "some param with required argument")('t', "true", HandlerStoreTrue(&flag), "Some arg with handler")("global", SimpleHander, "Another arg with handler"); + opts('v', "version", "print version information")('a', "abstract", "some abstract param", true)('b', "buffer", "SIZE", "some param with argument")('c', "count", "SIZE", "some param with required argument")('t', "true", HandlerStoreTrue(&flag), "Some arg with handler")("global", SimpleHander, "Another arg with handler"); { gSimpleFlag = false; @@ -758,7 +758,7 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { { UNIT_ASSERT_EXCEPTION( TOptsParseResultTestWrapper(&opts, V({"cmd", "--true"})), - TUsageException); + TUsageException); } { @@ -777,7 +777,7 @@ Y_UNIT_TEST_SUITE(TLastGetoptTests) { // Should throw TUsageException. Other exception types, no exceptions at all and exit(1) are failures UNIT_ASSERT_EXCEPTION( TOptsParseResultException(&opts, Y_ARRAY_SIZE(argv), argv), - TUsageException); + TUsageException); } Y_UNIT_TEST(TestFreeArgsStoreResult) { diff --git a/library/cpp/getopt/ut/opt2_ut.cpp b/library/cpp/getopt/ut/opt2_ut.cpp index 0e7464747c..4f7b615037 100644 --- a/library/cpp/getopt/ut/opt2_ut.cpp +++ b/library/cpp/getopt/ut/opt2_ut.cpp @@ -1,5 +1,5 @@ #include <library/cpp/getopt/opt2.h> - + #include <library/cpp/testing/unittest/registar.h> //using namespace NLastGetopt; @@ -8,25 +8,25 @@ Y_UNIT_TEST_SUITE(Opt2Test) { Y_UNIT_TEST(TestSimple) { int argc = 8; char* argv[] = { - (char*)"cmd", - (char*)"--aaaa=aaaa", - (char*)"zz", - (char*)"-x1", - (char*)"-x2", - (char*)"-c", - (char*)"-d8", - (char*)"ww", + (char*)"cmd", + (char*)"--aaaa=aaaa", + (char*)"zz", + (char*)"-x1", + (char*)"-x2", + (char*)"-c", + (char*)"-d8", + (char*)"ww", }; Opt2 opt(argc, argv, "A:b:cd:e:x:", 2, "aaaa=A"); - const char* edef = "edef"; - const char* a = opt.Arg('A', "<var_name> - usage of -A"); - int b = opt.Int('b', "<var_name> - usage of -b", 2); - bool c = opt.Has('c', "usage of -c"); - int d = opt.Int('d', "<var_name> - usage of -d", 13); - const char* e = opt.Arg('e', "<unused> - only default is really used", edef); - const TVector<const char*>& x = opt.MArg('x', "<var_name> - usage of -x"); + const char* edef = "edef"; + const char* a = opt.Arg('A', "<var_name> - usage of -A"); + int b = opt.Int('b', "<var_name> - usage of -b", 2); + bool c = opt.Has('c', "usage of -c"); + int d = opt.Int('d', "<var_name> - usage of -d", 13); + const char* e = opt.Arg('e', "<unused> - only default is really used", edef); + const TVector<const char*>& x = opt.MArg('x', "<var_name> - usage of -x"); UNIT_ASSERT(!opt.AutoUsage("<L> <M>")); UNIT_ASSERT_VALUES_EQUAL("aaaa", a); @@ -46,17 +46,17 @@ Y_UNIT_TEST_SUITE(Opt2Test) { Y_UNIT_TEST(TestErrors1) { int argc = 4; char* argv[] = { - (char*)"cmd", - (char*)"zz", - (char*)"-c", - (char*)"-e", + (char*)"cmd", + (char*)"zz", + (char*)"-c", + (char*)"-e", }; Opt2 opt(argc, argv, "ce:", 2); - const char* edef = "edef"; - bool c = opt.Has('c', "usage of -c"); - const char* e = opt.Arg('e', "<unused> - only default is really used", edef); + const char* edef = "edef"; + bool c = opt.Has('c', "usage of -c"); + const char* e = opt.Arg('e', "<unused> - only default is really used", edef); UNIT_ASSERT(c); UNIT_ASSERT_VALUES_EQUAL((void*)edef, e); } diff --git a/library/cpp/getopt/ut/opt_ut.cpp b/library/cpp/getopt/ut/opt_ut.cpp index 441aa493a0..031105b4cb 100644 --- a/library/cpp/getopt/ut/opt_ut.cpp +++ b/library/cpp/getopt/ut/opt_ut.cpp @@ -1,5 +1,5 @@ #include <library/cpp/getopt/opt.h> - + #include <library/cpp/testing/unittest/registar.h> #include <util/string/vector.h> @@ -7,7 +7,7 @@ Y_UNIT_TEST_SUITE(OptTest) { Y_UNIT_TEST(TestSimple) { int argc = 3; char* argv[] = { - (char*)"cmd", (char*)"-x"}; + (char*)"cmd", (char*)"-x"}; Opt opt(argc, argv, ""); opt.Err = false; // be quiet UNIT_ASSERT_VALUES_EQUAL('?', opt.Get()); @@ -18,9 +18,9 @@ Y_UNIT_TEST_SUITE(OptTest) { Y_UNIT_TEST(TestFreeArguments) { Opt::Ion options[] = { - {"some-option", Opt::WithArg, nullptr, 123}, - {nullptr, Opt::WithoutArg, nullptr, 0}}; - const char* argv[] = {"cmd", "ARG1", "-some-option", "ARG2", "ARG3", nullptr}; + {"some-option", Opt::WithArg, nullptr, 123}, + {nullptr, Opt::WithoutArg, nullptr, 0}}; + const char* argv[] = {"cmd", "ARG1", "-some-option", "ARG2", "ARG3", nullptr}; int argc = 5; Opt opts(argc, argv, "", options); @@ -30,10 +30,10 @@ Y_UNIT_TEST_SUITE(OptTest) { Y_UNIT_TEST(TestLongOption) { const int SOME_OPTION_ID = 12345678; Opt::Ion options[] = { - {"some-option", Opt::WithArg, nullptr, SOME_OPTION_ID}, - {nullptr, Opt::WithoutArg, nullptr, 0}}; + {"some-option", Opt::WithArg, nullptr, SOME_OPTION_ID}, + {nullptr, Opt::WithoutArg, nullptr, 0}}; for (int doubleDash = 0; doubleDash <= 1; ++doubleDash) { - const char* argv[] = {"cmd", "ARG1", (doubleDash ? "--some-option" : "-some-option"), "ARG2", "ARG3", nullptr}; + const char* argv[] = {"cmd", "ARG1", (doubleDash ? "--some-option" : "-some-option"), "ARG2", "ARG3", nullptr}; int argc = 5; Opt opts(argc, argv, "", options); @@ -42,7 +42,7 @@ Y_UNIT_TEST_SUITE(OptTest) { while ((optlet = opts.Get()) != EOF) { if (optlet == SOME_OPTION_ID) { optionValue = opts.GetArg(); - } else { + } else { UNIT_FAIL("don't expected any options, except -some-option"); } } diff --git a/library/cpp/getopt/ut/posix_getopt_ut.cpp b/library/cpp/getopt/ut/posix_getopt_ut.cpp index b6d374bf28..549a5ae3a2 100644 --- a/library/cpp/getopt/ut/posix_getopt_ut.cpp +++ b/library/cpp/getopt/ut/posix_getopt_ut.cpp @@ -1,5 +1,5 @@ #include <library/cpp/getopt/posix_getopt.h> - + #include <library/cpp/testing/unittest/registar.h> using namespace NLastGetopt; @@ -7,8 +7,8 @@ using namespace NLastGetopt; Y_UNIT_TEST_SUITE(TPosixGetoptTest) { Y_UNIT_TEST(TestSimple) { int argc = 6; - const char* argv0[] = {"program", "-b", "-f1", "-f", "2", "zzzz"}; - char** const argv = (char**)argv0; + const char* argv0[] = {"program", "-b", "-f1", "-f", "2", "zzzz"}; + char** const argv = (char**)argv0; NLastGetopt::optreset = 1; UNIT_ASSERT_VALUES_EQUAL('b', NLastGetopt::getopt(argc, argv, "bf:")); @@ -25,14 +25,14 @@ Y_UNIT_TEST_SUITE(TPosixGetoptTest) { int daggerset = 0; /* options descriptor */ const NLastGetopt::option longopts[] = { - {"buffy", no_argument, nullptr, 'b'}, - {"fluoride", required_argument, nullptr, 'f'}, - {"daggerset", no_argument, &daggerset, 1}, - {nullptr, 0, nullptr, 0}}; + {"buffy", no_argument, nullptr, 'b'}, + {"fluoride", required_argument, nullptr, 'f'}, + {"daggerset", no_argument, &daggerset, 1}, + {nullptr, 0, nullptr, 0}}; int argc = 7; - const char* argv0[] = {"program", "-b", "--buffy", "-f1", "--fluoride=2", "--daggerset", "zzzz"}; - char** const argv = (char**)argv0; + const char* argv0[] = {"program", "-b", "--buffy", "-f1", "--fluoride=2", "--daggerset", "zzzz"}; + char** const argv = (char**)argv0; int longIndex; @@ -53,14 +53,14 @@ Y_UNIT_TEST_SUITE(TPosixGetoptTest) { int daggerset = 0; /* options descriptor */ const NLastGetopt::option longopts[] = { - {"buffy", no_argument, nullptr, 'b'}, - {"fluoride", required_argument, nullptr, 'f'}, - {"daggerset", no_argument, &daggerset, 1}, - {nullptr, 0, nullptr, 0}}; + {"buffy", no_argument, nullptr, 'b'}, + {"fluoride", required_argument, nullptr, 'f'}, + {"daggerset", no_argument, &daggerset, 1}, + {nullptr, 0, nullptr, 0}}; int argc = 7; - const char* argv0[] = {"program", "aa", "-b", "bb", "cc", "--buffy", "dd"}; - char** const argv = (char**)argv0; + const char* argv0[] = {"program", "aa", "-b", "bb", "cc", "--buffy", "dd"}; + char** const argv = (char**)argv0; NLastGetopt::optreset = 1; UNIT_ASSERT_VALUES_EQUAL('b', NLastGetopt::getopt_long(argc, argv, "bf:", longopts, nullptr)); @@ -72,13 +72,13 @@ Y_UNIT_TEST_SUITE(TPosixGetoptTest) { Y_UNIT_TEST(TestNoOptionsOptionsWithDoubleDash) { const NLastGetopt::option longopts[] = { - {"buffy", no_argument, nullptr, 'b'}, - {"fluoride", no_argument, nullptr, 'f'}, - {nullptr, 0, nullptr, 0}}; + {"buffy", no_argument, nullptr, 'b'}, + {"fluoride", no_argument, nullptr, 'f'}, + {nullptr, 0, nullptr, 0}}; int argc = 2; - const char* argv0[] = {"program", "--bf"}; - char** const argv = (char**)argv0; + const char* argv0[] = {"program", "--bf"}; + char** const argv = (char**)argv0; NLastGetopt::optreset = 1; UNIT_ASSERT_VALUES_EQUAL('?', NLastGetopt::getopt_long(argc, argv, "bf", longopts, nullptr)); @@ -86,32 +86,32 @@ Y_UNIT_TEST_SUITE(TPosixGetoptTest) { Y_UNIT_TEST(TestLongOnly) { const NLastGetopt::option longopts[] = { - {"foo", no_argument, nullptr, 'F'}, - {"fluoride", no_argument, nullptr, 'f'}, - {"ogogo", no_argument, nullptr, 'o'}, - {nullptr, 0, nullptr, 0}}; + {"foo", no_argument, nullptr, 'F'}, + {"fluoride", no_argument, nullptr, 'f'}, + {"ogogo", no_argument, nullptr, 'o'}, + {nullptr, 0, nullptr, 0}}; int argc = 4; - const char* argv0[] = {"program", "--foo", "-foo", "-fo"}; - char** const argv = (char**)argv0; + const char* argv0[] = {"program", "--foo", "-foo", "-fo"}; + char** const argv = (char**)argv0; NLastGetopt::optreset = 1; UNIT_ASSERT_VALUES_EQUAL('F', NLastGetopt::getopt_long_only(argc, argv, "fo", longopts, nullptr)); UNIT_ASSERT_VALUES_EQUAL('F', NLastGetopt::getopt_long_only(argc, argv, "fo", longopts, nullptr)); UNIT_ASSERT_VALUES_EQUAL('f', NLastGetopt::getopt_long_only(argc, argv, "fo", longopts, nullptr)); UNIT_ASSERT_VALUES_EQUAL('o', NLastGetopt::getopt_long_only(argc, argv, "fo", longopts, nullptr)); - UNIT_ASSERT_VALUES_EQUAL(-1, NLastGetopt::getopt_long_only(argc, argv, "fo", longopts, nullptr)); + UNIT_ASSERT_VALUES_EQUAL(-1, NLastGetopt::getopt_long_only(argc, argv, "fo", longopts, nullptr)); } Y_UNIT_TEST(TestLongWithoutOnlySingleDashNowAllowed) { const NLastGetopt::option longopts[] = { - {"foo", no_argument, nullptr, 'F'}, - {"zoo", no_argument, nullptr, 'z'}, - {nullptr, 0, nullptr, 0}}; + {"foo", no_argument, nullptr, 'F'}, + {"zoo", no_argument, nullptr, 'z'}, + {nullptr, 0, nullptr, 0}}; int argc = 2; - const char* argv0[] = {"program", "-foo"}; - char** const argv = (char**)argv0; + const char* argv0[] = {"program", "-foo"}; + char** const argv = (char**)argv0; NLastGetopt::optreset = 1; UNIT_ASSERT_VALUES_EQUAL('?', NLastGetopt::getopt_long(argc, argv, "z", longopts, nullptr)); diff --git a/library/cpp/getopt/ut/ygetopt_ut.cpp b/library/cpp/getopt/ut/ygetopt_ut.cpp index a76f117216..99fa51281e 100644 --- a/library/cpp/getopt/ut/ygetopt_ut.cpp +++ b/library/cpp/getopt/ut/ygetopt_ut.cpp @@ -1,45 +1,45 @@ #include <library/cpp/getopt/ygetopt.h> - + #include <library/cpp/testing/unittest/registar.h> - -class TGetOptTest: public TTestBase { - UNIT_TEST_SUITE(TGetOptTest); - UNIT_TEST(TestGetOpt); - UNIT_TEST_EXCEPTION(TestZeroArgC, yexception); - UNIT_TEST_SUITE_END(); - -public: - void TestGetOpt(); - void TestZeroArgC(); -}; - -UNIT_TEST_SUITE_REGISTRATION(TGetOptTest); - -void TGetOptTest::TestZeroArgC() { + +class TGetOptTest: public TTestBase { + UNIT_TEST_SUITE(TGetOptTest); + UNIT_TEST(TestGetOpt); + UNIT_TEST_EXCEPTION(TestZeroArgC, yexception); + UNIT_TEST_SUITE_END(); + +public: + void TestGetOpt(); + void TestZeroArgC(); +}; + +UNIT_TEST_SUITE_REGISTRATION(TGetOptTest); + +void TGetOptTest::TestZeroArgC() { TGetOpt opt(0, nullptr, ""); -} - -void TGetOptTest::TestGetOpt() { - const char* argv[] = { - "/usr/bin/bash", - "-f", - "-p", - "qwerty123", - "-z", - "-q", - nullptr}; - +} + +void TGetOptTest::TestGetOpt() { + const char* argv[] = { + "/usr/bin/bash", + "-f", + "-p", + "qwerty123", + "-z", + "-q", + nullptr}; + TString res; const TString format = "qzp:f"; - TGetOpt opt(sizeof(argv) / sizeof(*argv) - 1, argv, format); - - for (TGetOpt::TIterator it = opt.Begin(); it != opt.End(); ++it) { - res += it->Key(); - - if (it->HaveArg()) { - res += it->Arg(); - } - } - - UNIT_ASSERT_EQUAL(res, "fpqwerty123zq"); -} + TGetOpt opt(sizeof(argv) / sizeof(*argv) - 1, argv, format); + + for (TGetOpt::TIterator it = opt.Begin(); it != opt.End(); ++it) { + res += it->Key(); + + if (it->HaveArg()) { + res += it->Arg(); + } + } + + UNIT_ASSERT_EQUAL(res, "fpqwerty123zq"); +} diff --git a/library/cpp/getopt/ya.make b/library/cpp/getopt/ya.make index 6df23b22b2..18adcd6051 100644 --- a/library/cpp/getopt/ya.make +++ b/library/cpp/getopt/ya.make @@ -1,4 +1,4 @@ -LIBRARY() +LIBRARY() OWNER(pg) diff --git a/library/cpp/getopt/ygetopt.h b/library/cpp/getopt/ygetopt.h index fd018b3128..559a24bfe8 100644 --- a/library/cpp/getopt/ygetopt.h +++ b/library/cpp/getopt/ygetopt.h @@ -1,3 +1,3 @@ #pragma once - + #include <library/cpp/getopt/small/ygetopt.h> |