#pragma once #include "last_getopt.h" #include #include // 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 Opts_; THolder 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 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"; \ } \ } \ }