diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/getopt/small/opt.h | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/getopt/small/opt.h')
-rw-r--r-- | library/cpp/getopt/small/opt.h | 142 |
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"; \ + } \ + } \ + } |