aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/getopt/small/modchooser.h
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/getopt/small/modchooser.h
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/getopt/small/modchooser.h')
-rw-r--r--library/cpp/getopt/small/modchooser.h215
1 files changed, 215 insertions, 0 deletions
diff --git a/library/cpp/getopt/small/modchooser.h b/library/cpp/getopt/small/modchooser.h
new file mode 100644
index 0000000000..0a8de6d50b
--- /dev/null
+++ b/library/cpp/getopt/small/modchooser.h
@@ -0,0 +1,215 @@
+#pragma once
+
+#include "last_getopt_opts.h"
+
+#include <util/generic/map.h>
+#include <util/generic/string.h>
+#include <util/generic/vector.h>
+
+#include <functional>
+
+//! Mode function with vector of cli arguments.
+using TMainFunctionPtrV = std::function<int(const TVector<TString>&)> ;
+using TMainFunctionRawPtrV = int (*)(const TVector<TString>& argv);
+
+//! Mode function with classic argc and argv arguments.
+using TMainFunctionPtr = std::function<int(int, const char**)> ;
+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 ~TMainClassV() = default;
+};
+
+//! Mode class with classic argc and argv arguments.
+class TMainClass {
+public:
+ virtual int operator()(int argc, const char** argv) = 0;
+ virtual ~TMainClass() = default;
+};
+
+//! Function to handle '--version' parameter
+typedef void (*TVersionHandlerPtr)();
+
+/*! Main class for handling different modes in single tool.
+ *
+ * You can add modes for this class, use autogenerated help with
+ * list of modes and automaticly call necessary mode in run().
+ *
+ * In first argv element mode get joined by space tool name and
+ * current mode name.
+ */
+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);
+ void AddMode(const TString& mode, TMainFunctionPtr func, const TString& description, bool hidden = false, bool noCompletion = false);
+ void AddMode(const TString& mode, TMainFunctionPtrV func, const TString& description, bool hidden = false, bool noCompletion = false);
+ void AddMode(const TString& mode, TMainClass* func, const TString& description, bool hidden = false, bool noCompletion = false);
+ void AddMode(const TString& mode, TMainClassV* func, const TString& description, bool hidden = false, bool noCompletion = false);
+
+ //! Hidden groups won't be displayed in 'help' block
+ void AddGroupModeDescription(const TString& description, bool hidden = false, bool noCompletion = false);
+
+ //! Set default mode (if not specified explicitly)
+ void SetDefaultMode(const TString& mode);
+
+ void AddAlias(const TString& alias, const TString& mode);
+
+ //! Set main program description.
+ void SetDescription(const TString& descr);
+
+ //! Set modes help option name (-? is by default)
+ void SetModesHelpOption(const TString& helpOption);
+
+ //! Specify handler for '--version' parameter
+ void SetVersionHandler(TVersionHandlerPtr handler);
+
+ //! Set description show mode
+ void SetSeparatedMode(bool separated = true);
+
+ //! Set separation string
+ void SetSeparationString(const TString& str);
+
+ //! Set short command representation in Usage block
+ void SetPrintShortCommandInUsage(bool printShortCommandInUsage);
+
+ void DisableSvnRevisionOption();
+
+ void AddCompletions(TString progName, const TString& name = "completion", bool hidden = false, bool noCompletion = false);
+
+ /*! Run appropriate mode.
+ *
+ * In this method following things happen:
+ * 1) If first argument is -h/--help/-? then print short description of
+ * all modes and exit with zero code.
+ * 2) If first argument is -v/--version and version handler is specified,
+ * then call it and exit with zero code.
+ * 3) Find mode with the same name as first argument. If it's found then
+ * call it and return its return code.
+ * 4) If appropriate mode is not found - return non-zero code.
+ */
+ 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;
+
+ void PrintHelp(const TString& progName) const;
+
+ struct TMode {
+ TString Name;
+ TMainClass* Main;
+ TString Description;
+ bool Hidden;
+ bool NoCompletion;
+ TVector<TString> Aliases;
+
+ TMode()
+ : Main(nullptr)
+ {
+ }
+
+ TMode(const TString& name, TMainClass* main, const TString& descr, bool hidden, bool noCompletion);
+
+ // Full name includes primary name and aliases. Also, will add ANSI colors.
+ size_t CalculateFullNameLen() const;
+ TString FormatFullName(size_t pad) const;
+ };
+
+ TVector<const TMode*> GetUnsortedModes() const {
+ auto ret = TVector<const TMode*>(Reserve(UnsortedModes.size()));
+ for (auto& mode : UnsortedModes) {
+ ret.push_back(mode.Get());
+ }
+ return ret;
+ }
+
+ TVersionHandlerPtr GetVersionHandler() const;
+
+ bool IsSvnRevisionOptionDisabled() const;
+
+private:
+ //! Main program description.
+ TString Description;
+
+ //! Help option for modes.
+ TString ModesHelpOption;
+
+ //! Wrappers around all modes.
+ TVector<THolder<TMainClass>> Wrappers;
+
+ //! Modes
+ TMap<TString, TMode*> Modes;
+
+ TString DefaultMode;
+
+ //! Handler for '--version' parameter
+ TVersionHandlerPtr VersionHandler;
+
+ //! When set to true, show descriptions unsorted and display separators
+ bool ShowSeparated;
+
+ //! When set to true, disables --svnrevision option, useful for opensource (git hosted) projects
+ bool SvnRevisionOptionDisabled;
+
+ //! When true - will print only 'mode name' in 'Usage' block
+ bool PrintShortCommandInUsage;
+
+ //! Text string used when displaying each separator
+ TString SeparationString;
+
+ //! Unsorted list of options
+ TVector<THolder<TMode>> UnsortedModes;
+
+ //! Mode that generates completions
+ THolder<TMainClass> CompletionsGenerator;
+};
+
+//! Mode class that allows introspecting its console arguments.
+class TMainClassArgs: public TMainClass {
+public:
+ int operator()(int argc, const char** argv) final;
+
+public:
+ //! Run this mode.
+ int Run(int argc, const char** argv);
+
+ //! Get console arguments for this mode.
+ const NLastGetopt::TOpts& GetOptions();
+
+protected:
+ //! Fill given empty `TOpts` with options.
+ virtual void RegisterOptions(NLastGetopt::TOpts& opts);
+
+ //! Actual mode logic. Takes parsed options and returns exit code.
+ virtual int DoRun(NLastGetopt::TOptsParseResult&& parsedOptions) = 0;
+
+private:
+ TMaybe<NLastGetopt::TOpts> Opts_;
+};
+
+//! Mode class that uses sub-modes to dispatch commands further.
+class TMainClassModes: public TMainClass {
+public:
+ int operator()(int argc, const char** argv) final;
+
+public:
+ //! Run this mode.
+ int Run(int argc, const char** argv);
+
+ //! Get sub-modes for this mode.
+ const TModChooser& GetSubModes();
+
+protected:
+ //! Fill given modchooser with sub-modes.
+ virtual void RegisterModes(TModChooser& modes);
+
+private:
+ TMaybe<TModChooser> Modes_;
+};