123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- #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"; \
- } \
- } \
- }
|