aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/getopt/small/opt.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/opt.h
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/getopt/small/opt.h')
-rw-r--r--library/cpp/getopt/small/opt.h142
1 files changed, 142 insertions, 0 deletions
diff --git a/library/cpp/getopt/small/opt.h b/library/cpp/getopt/small/opt.h
new file mode 100644
index 0000000000..ecb57439bc
--- /dev/null
+++ b/library/cpp/getopt/small/opt.h
@@ -0,0 +1,142 @@
+#pragma once
+
+#include "last_getopt.h"
+
+#include <util/generic/ptr.h>
+#include <util/generic/noncopyable.h>
+
+// implementation of Opt class using last getopt
+
+/*
+ short-options syntax:
+
+ opt-letter ::=
+ [^: ]
+
+ opt-string ::=
+ '+'|'-'?({opt-letter}':'{0,2})*
+
+ example: "AbCx:y:z::"
+ {A,b,C} options without argument
+ {x,y} options with argument
+ {z} option with optional argument
+
+ 1. shortopts begins with '-' :=> RETURN_IN_ORDER
+ == non-option forces getopt to return 1 and to place non-option into optarg
+
+ 2. shortopts begins with '+' :=> REQUIRE_ORDER
+ GetEnv(_POSIX_OPTION_ORDER) :=> REQUIRE_ORDER
+ == 1st non-option forces getopt to return EOF
+
+ 3. default :=> PERMUTE
+ == exchange options with non-options and place all options first
+
+ 4. '--' command line argument forces getopt to stop parsing and to return EOF
+ in any case
+
+ long options should begin by '+' sign
+ or when (_getopt_long_only = 1) by '-' sign
+
+ struct option {
+ char *name : option name
+ int has_arg: 0 | 1 | 2 = without | with | optional argument
+ int *flag : if (flag != 0) then getopt returns 0 and stores val into *flag
+ int val : if (flag == 0) then getopt returns val
+ }
+
+ Example:
+
+ struct option my_opts[] = {
+ { "delete", 0, &deletion_flag, DEL }, -- returns 0, deletion_flag := DEL
+ { "add", 1, NULL, 'a' }, -- returns 'a', argument in optarg
+ { NULL }
+ }
+*/
+
+#define OPT_RETURN_IN_ORDER "-"
+#define OPT_REQUIRE_ORDER "+"
+#define OPT_DONT_STORE_ARG ((void*)0)
+
+class Opt : TNonCopyable {
+public:
+ enum HasArg { WithoutArg,
+ WithArg,
+ PossibleArg };
+
+ struct Ion {
+ const char* name;
+ HasArg has_arg;
+ int* flag;
+ int val;
+ };
+
+private:
+ THolder<NLastGetopt::TOpts> Opts_;
+ 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:
+ Opt(int argc, char* argv[], const char* optString, const Ion* longOptions = nullptr, bool longOnly = false, bool isOpen = false);
+ Opt(int argc, const char* argv[], const char* optString, const Ion* longOptions = nullptr, bool longOnly = false, bool isOpen = false);
+
+ // Get() means next
+ int Get();
+ int Get(int* longOptionIndex);
+ int operator()() {
+ return Get();
+ }
+
+ 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 */
+
+ int Ind; /* command line index */
+ bool Err; /* flag to print error messages */
+
+ int GetArgC() const;
+ const char** GetArgV() const;
+
+ void DummyHelp(IOutputStream& os = Cerr);
+};
+
+// 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;
+
+#define OPTION_HANDLE(opt, handle) \
+ OPTION_HANDLE_BEGIN(opt) \
+ handle; \
+ OPTION_HANDLE_END
+
+#define OPTION_HANDLING_EPILOG \
+ default: \
+ ythrow yexception() << "unknown optlet"; \
+ } \
+ } \
+ }