opt.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #pragma once
  2. #include "last_getopt.h"
  3. #include <util/generic/ptr.h>
  4. #include <util/generic/noncopyable.h>
  5. // implementation of Opt class using last getopt
  6. /*
  7. short-options syntax:
  8. opt-letter ::=
  9. [^: ]
  10. opt-string ::=
  11. '+'|'-'?({opt-letter}':'{0,2})*
  12. example: "AbCx:y:z::"
  13. {A,b,C} options without argument
  14. {x,y} options with argument
  15. {z} option with optional argument
  16. 1. shortopts begins with '-' :=> RETURN_IN_ORDER
  17. == non-option forces getopt to return 1 and to place non-option into optarg
  18. 2. shortopts begins with '+' :=> REQUIRE_ORDER
  19. GetEnv(_POSIX_OPTION_ORDER) :=> REQUIRE_ORDER
  20. == 1st non-option forces getopt to return EOF
  21. 3. default :=> PERMUTE
  22. == exchange options with non-options and place all options first
  23. 4. '--' command line argument forces getopt to stop parsing and to return EOF
  24. in any case
  25. long options should begin by '+' sign
  26. or when (_getopt_long_only = 1) by '-' sign
  27. struct option {
  28. char *name : option name
  29. int has_arg: 0 | 1 | 2 = without | with | optional argument
  30. int *flag : if (flag != 0) then getopt returns 0 and stores val into *flag
  31. int val : if (flag == 0) then getopt returns val
  32. }
  33. Example:
  34. struct option my_opts[] = {
  35. { "delete", 0, &deletion_flag, DEL }, -- returns 0, deletion_flag := DEL
  36. { "add", 1, NULL, 'a' }, -- returns 'a', argument in optarg
  37. { NULL }
  38. }
  39. */
  40. #define OPT_RETURN_IN_ORDER "-"
  41. #define OPT_REQUIRE_ORDER "+"
  42. #define OPT_DONT_STORE_ARG ((void*)0)
  43. class Opt : TNonCopyable {
  44. public:
  45. enum HasArg { WithoutArg,
  46. WithArg,
  47. PossibleArg };
  48. struct Ion {
  49. const char* name;
  50. HasArg has_arg;
  51. int* flag;
  52. int val;
  53. };
  54. private:
  55. THolder<NLastGetopt::TOpts> Opts_;
  56. THolder<NLastGetopt::TOptsParser> OptsParser_;
  57. const Ion* Ions_;
  58. bool GotError_;
  59. void Init(int argc, char* argv[], const char* optString, const Ion* longOptions = nullptr, bool longOnly = false, bool isOpen = false);
  60. public:
  61. Opt(int argc, char* argv[], const char* optString, const Ion* longOptions = nullptr, bool longOnly = false, bool isOpen = false);
  62. Opt(int argc, const char* argv[], const char* optString, const Ion* longOptions = nullptr, bool longOnly = false, bool isOpen = false);
  63. // Get() means next
  64. int Get();
  65. int Get(int* longOptionIndex);
  66. int operator()() {
  67. return Get();
  68. }
  69. const char* GetArg() const {
  70. return Arg;
  71. }
  72. TVector<TString> GetFreeArgs() const {
  73. return NLastGetopt::TOptsParseResult(&*Opts_, GetArgC(), GetArgV()).GetFreeArgs();
  74. }
  75. // obsolete, use GetArg() instead
  76. char* Arg; /* option argument if any or NULL */
  77. int Ind; /* command line index */
  78. bool Err; /* flag to print error messages */
  79. int GetArgC() const;
  80. const char** GetArgV() const;
  81. void DummyHelp(IOutputStream& os = Cerr);
  82. };
  83. // call before getopt. returns non-negative int, removing it from arguments (not found: -1)
  84. // Example: returns 11 for "progname -11abc", -1 for "progname -a11"
  85. int opt_get_number(int& argc, char* argv[]);
  86. #define OPTION_HANDLING_PROLOG \
  87. { \
  88. int optlet; \
  89. while (EOF != (optlet = opt.Get())) { \
  90. switch (optlet) {
  91. #define OPTION_HANDLING_PROLOG_ANON(S) \
  92. { \
  93. Opt opt(argc, argv, (S)); \
  94. int optlet; \
  95. while (EOF != (optlet = opt.Get())) { \
  96. switch (optlet) {
  97. #define OPTION_HANDLE_BEGIN(opt) case opt: {
  98. #define OPTION_HANDLE_END \
  99. } \
  100. break;
  101. #define OPTION_HANDLE(opt, handle) \
  102. OPTION_HANDLE_BEGIN(opt) \
  103. handle; \
  104. OPTION_HANDLE_END
  105. #define OPTION_HANDLING_EPILOG \
  106. default: \
  107. ythrow yexception() << "unknown optlet"; \
  108. } \
  109. } \
  110. }